|小图标,大学问( 三 )


不过 , svg 的特点 , 让我们还有了一些另外的用法 。
首先 , 可以把 svg 内联到 html 中 。 svg 和 html 在语法上非常像 , 都是 xml 语系 , 只是使用了不同的命名空间(xmlns) , 因此我们可以把 svg 作为一个元素内联到 html 中 , 现代浏览器可以正确地解释它们 。 这种用法比较自然 , html 中引入的 css 也同样可以作用于 svg 内部的元素上 , 图文可以无缝整合在一起 。
不过这种用法有两个问题 。 其一是 svg 中各个元素的 id 会并入页面的命名空间中 , 比如在 svg 中引用了一个名为 a 的过滤器 , 那么如果 html 或另一个 svg 中也定义了它 , 就会互相冲突 。 在稍大点的项目中要解决这种冲突会相当麻烦 。 其二是如果这个图标出现很多次 , 它的内容就会在 html 中重复很多遍 , 体积也会相应的增大 。
好在 , svg 有一种机制可以解决这个问题 , 也就是use 标签 。 使用 use 标签 , 你可以根据 id 引用本页面中的 svg 元素 , 甚至来自其它 svg 文件中的元素 。 比如要引用本页面中的 id 为 a 的 rect 元素 , 你只需要写 <use xlink:href=''#a''>即可 , 并且在这里你可以指定自己的 svg 属性 , 以覆盖原始元素上的 svg 设置 。 这样一来 , 图标内容被重复很多遍的问题就解决了 。 如果写成 <use xlink:href=''path/to/file.svg#a''> 则可以引用外部文件 path/to/file.svg 中定义的元素 , 那么 id 冲突的问题也同样解决了 , 因为它们不在同一个命名空间 。
不过 , 这种方式相对于字体图标还有两个缺点:
一是图标的颜色不会自动跟随文字颜色 。 比如原始元素定义的 rect 是红色的 , 那么无论你把它混排到什么颜色的文字中 , 它都是红色的 。 难道我们要在每个使用它的地方都手动覆盖一下颜色吗?当然不必 , 我们还有另一个特性可以解决这个问题 , 那就是 currentColor 。 这是一个预定义的特殊颜色值 , 它的意思就是取当前的文字颜色 。 比如当你写<rect fill=''currentColor''></rect> 时 , 把它混排到灰色文字中 , 这个rect的填充色就是灰色的 , 混排到蓝色文字中就是蓝色的 。 而且 , 这个图标的其它部分你仍然可以指定特定的颜色 , 比如图标主体部分跟随文字颜色 , 而某个特殊区域总是显示为蓝色 。经过这样的处理之后 , 你不但可以弥补相对于字体图标的缺点 , 还可以更进一步 , 支持彩色图标了!即使你不需要彩色图标 , 凭借 svg 对元素透明度的支持 , 也可以让你的图标比字体图标更加丰富多彩 。
二是图标的大小不会自动跟随字体大小 。 不过这个就好解决了 , 因为 css 中有一个特性就是把当前字号作为尺寸单位 , 也就是 em , 比如图标大小设置为1em就会让图标的实际尺寸跟当前字号一致 。
当代:合字(Ligature)
你知道“囍”字吗?严格来说 , 它不是一个字 , 而是一个“合字” 。 也就是说这是两个汉字 , 只是显示成了一个字的样子 。 只是因为它非常常见 , 所以在字库中给了它一个单独的位置 。 但是大多数类似的文字是得不到这种特殊待遇的 , 比如“孔孟好学”的合体 , 以及“biangbiang面”中的“biang”字;字母上的声调(比如汉语拼音)也是合字 。
那么 , 要如何用标准的方式来显示这些合字呢?实际上 , 现代的字体库早就已经支持合字了 , 只是在现实中用得不多 , 一般人没怎么注意罢了 。 不过 , 在图标领域 , 它重新找回了用武之地 。 我所知道的最早使用合字的图标体系是 Google 的 Material Design , 比如用 <i class=''material-icons''>home</i>就可以显示出一座房子 , 它是怎么工作的呢?实际上 , material-icons 类为这个 i元素指定了一个支持合字的字体库:'Material Icons' , 然后就会在字体库中检索出 home 这个合字对应的单字 , 并且把那个单字显示出来就可以了 。 换句话说 , home 是某个单字的别名 。


推荐阅读