我在这里谈论了SVG的<use>
并使用它来构建图标系统 。 <use>
在于,您可以仅引用在其他地方定义的某些SVG的一部分,并仅将该部分画在其他地方。 借助该功能,您可以在其中构建整个系统,从而解决了我们过去使用CSS精灵和图标字体解决的“一个请求中有很多图像,因为那是超高效的”问题。
但是<use>
表示嵌入式SVG。 当您要在SVG-as- <img>
或SVG-as background-image
使用较大的SVG的一部分时,它没有帮助。 那就是片段标识符的来源。
准备好SVG
一种实现方法是将SVG(精灵,我想称其为精灵)布置得像图形“ CSS”精灵。
我们具体是这样做的,因为我们最终将要移动一些viewBox
数字以仅显示该图像的一部分,就像我们以前使用CSS Sprite一样。
在这个小小的迷你演示中,我们使用三个分别为32×32的图标。 因此文档为32×96。 我们可以这样看待viewBox的恶作剧:
整个文件检视框 | 0 0 32 96 |
只显示顶部图标viewBox | 0 0 32 32 |
只显示中间图标viewBox | 0 32 32 32 |
只显示底部图标viewBox | 0 64 32 32 |
viewBox
属性为:左,顶部,宽度,高度。 请注意,第二个属性,即top,每次加32。 我们只是显示整个文档的不同部分。
将那些特殊的viewBox添加到SVG本身中
您可以将这些特殊的特定viewBox
值放在<view>
元素中的SVG中,专门用于此目的:
<view id="icon-clock-view" viewBox="0 0 32 32" />
<view id="icon-heart-view" viewBox="0 32 32 32" />
<view id="icon-arrow-right-view" viewBox="0 64 32 32" />
现在,我们将能够从其他地方引用和使用这些值。
<view>
元素可以像这样独立运行,或者它们实际上可以包装其他元素,在这种情况下,当ID匹配时, viewBox
会viewBox
<!-- this viewBox takes over if current fragment identifer is #match-me -->
<view id="match-me" viewBox="0 64 32 32">
<rect ...>
</view>
在规范中演示这种事情 。
HTML的语法
要将那些特殊的viewBox
值应用于SVG-as- <img>
,您可以这样做:
<!-- top icon -->
<img src="sprite.svg#svgView(viewBox(0, 0, 32, 32))" alt="">
或者,如果您已经设置了<view>
元素,则可以按名称引用它们:
<!-- middle icon -->
<img src="sprite.svg#icon-heart-view" alt="">
CSS的语法
您可以在CSS的图像路径中声明一个特殊的viewBox
:
.icon-clock {
background: url("sprite.svg#svgView(viewBox(0, 0, 32, 32))") no-repeat;
}
或引用<view>
元素(如果已设置):
.icon-clock {
background: url(sprite.svg#icon-clock-view) no-repeat;
}
尽管…如果您通过CSS使用SVG并遇到了麻烦,以这种方式设置所有SVG,您可能只想使用CSS Sprite技术并改变背景:
.icon-heart {
background: url("sprite.svg") no-repeat;
background-size: 32px 96px;
background-position: 0 -32px;
}
我只是想将图标堆叠在一起。
如果所有图标都具有相同的viewBox
而您基本上只想根据需要隐藏/显示它们,则可以使操作变得容易一些。
将它们全部设计在相同的空间中(或使用可以做到这一点的构建工具或其他工具)。 在这里,我将每个图标放在一个具有唯一ID的组中。
然后,使隐藏/显示工作的技巧是嵌入一些CSS,该CSS 1)隐藏所有内容2)揭示具有匹配片段标识符CSS。 CSS是可以胜任的,因为:target
选择器 。
一起在SVG中:
<defs>
<style>
g {
display: none;
}
g:target {
display: inline;
}
</style>
</defs>
<g id="icon-clock">
<path d="M20.6,23.3L14,16.7V7.9h4v7.2l5.4,5.4L20.6,23.3z M16-0.1c-8.8,0-16,7.2-16,16s7.2,16,16,16s16-7.2,16-16S24.8-0.1,16-0.1z
M16,27.9c-6.6,0-12-5.4-12-12s5.4-12,12-12s12,5.4,12,12S22.6,27.9,16,27.9z"/>
</g>
<g id="icon-heart">
<path d="M32,11.2c0,2.7-1.2,5.1-3,6.8l0,0L19,28c-1,1-2,2-3,2s-2-1-3-2L3,18c-1.9-1.7-3-4.1-3-6.8C0,6.1,4.1,2,9.2,2
c2.7,0,5.1,1.2,6.8,3c1.7-1.9,4.1-3,6.8-3C27.9,1.9,32,6.1,32,11.2z"/>
</g>
<g id="icon-arrow-right">
<path d="M32,15.9l-16-16v10H0v12h16v10L32,15.9z"/>
</g>
浏览器支持
我可以使用曲目支持片段标识符。 不幸的是,它不是很简单,因为它可能在HTML中而不是CSS上运行,或者有怪癖,这取决于浏览器。
这是我的测试页:
请参阅CodePen上Chris Coyier ( @chriscoyier ) 撰写的 HTML和CSS中的Pen SVG片段标识符 。
我尚未对此做过详尽的浏览器支持说明,但以下是重点内容:
- Firefox可以正确执行所有操作。
- IE 11可以正确执行所有操作。 IE 9和10在
background-position
(挤压)有点奇怪,但在其他方面都可以使用。 -
当前版本的Chrome / Safari / Opera(38/8/25)可以很好地处理所有HTML更新:如果引用的<img>
技术,但没有CSS技术,包括background-position
技术。 眨眼前的歌剧是一样的,很有趣。<svg>
具有正确的width和height属性,则所有方法均按预期工作。 至少从Chrome(56)/ Opera开始。 - iOS 8.1唯一可以处理的是
<img>
引用<view>
。 - Android 4.4唯一正确的方法是背景位置(根本不使用片段标识符的背景位置)。 Android 5与上述的当前Chrome / Safari / Opera匹配。
连锁!
- 规格
- Simuari的SVG Stacks指向ErikMaelström 的演示和Bear Travis的演示 。
- Jorge Aznar的演示
- Peter Gasston的带片段标识符的更好的SVG精灵
- SVG Sprite Sheets通过Bear Travis