假设您正在使用内联 SVG,并且希望在状态更改时(例如更改类或在 :hover/:focus 时)更改元素中显示的 SVG 图标。您可以通过多种方法来实现这一点。
方法一:隐藏/显示 SVG 元素
包含两个图标
<a href="#0" class="expand-link">
<svg class="icon icon-expand" viewBox="0 0 32 32"><use xlink:href="#icon-expand"></use></svg>
<svg class="icon icon-contract" viewBox="0 0 32 32"><use xlink:href="#icon-contract"></use></svg>
</a>
默认隐藏一个
.expand-link .icon-contract {
display: none;
}
当状态更改时,交换 display 属性
.expand-link:hover .icon-expand,
.expand-link:active .icon-expand{
display: none;
}
.expand-link:hover .icon-contract,
.expand-link:active .icon-contract{
display: block;
}
查看 Chris Coyier 在 CodePen 上的示例 praEH (@chriscoyier)。
方法二:隐藏/显示路径
您将无法使用 <use>
技术(因为 HTML 元素上的状态更改发生在 <use>
创建的 Shadow DOM 之上的级别,因此 CSS 无法穿透),但如果内联 SVG 直接位于其中,您可以直接隐藏/显示形状元素。
<a href="#0"class="icon-expand-link">
<svg ... >
<path class="expand" d="M32 0v12l-etc"></path>
<path class="contract" d="M2 18h12v12l-etc"></path>
</svg>
</a>
.icon-expand-link .contract {
display: none;
}
.icon-expand-link:hover .expand {
display: none;
}
.icon-expand-link:hover .contract {
display: block;
}
查看 Chris Coyier 在 CodePen 上的示例 cCiBn (@chriscoyier)。
方法三:更改 xlink:href
使用 JavaScript,您可以更改 <use>
中引用的 SVG 片段。用 JavaScript 来做样式化的事情似乎很奇怪,但是,不重复标记是很好的,如果您引用 <symbol>
,<title>
和 <desc>
也会随之更改,这也很不错。
<a href="#0" class="expand-link">
<svg class="icon icon-expand" viewBox="0 0 32 32"><use id="target" xlink:href="#icon-expand"></use></svg>
</a>
$(".expand-link")
.on("mouseenter", function() {
$(this).find("use").attr("xlink:href", "#icon-contract");
})
.on("mouseleave", function() {
$(this).find("use").attr("xlink:href", "#icon-expand");
});
查看 Chris Coyier 在 CodePen 上的示例 Dqpib (@chriscoyier)。
方法四:使用 CSS 重设样式
请记住,您也可以使用 CSS 做很多事情。也许您不需要完全不同的形状集,但您可以只使用 CSS 更改内容,从而实质上创建一个新图标。
如果您没有设置 SVG 内部任何内容的样式,则可以直接在 SVG 上设置样式(本质上是跨越 Shadow DOM 边界)。此外,您可以执行 CSS 变换等操作来旋转/缩放/移动。
查看 Chris Coyier 在 CodePen 上的示例 JFjdl (@chriscoyier)。
不使用内联 SVG?
如果您没有使用内联 SVG,而是使用 SVG 作为 <img>,则此隐藏/显示内容或更改源应该可以正常工作。
如果您使用 SVG 作为 background-image
,更改源也是一种选择。另外请注意,即使您在 CSS 中使用 Data URI 来表示图标的多个版本,这也会显得臃肿,但如果它们非常相似,GZIP 可以很好地处理这种情况。
嗨,Chris
我真的很感谢你的 blob 文章,谢谢。你能告诉我为什么一些仅仅是视觉上的和表现性的东西应该在标记中表示,以及为什么不通过样式使用 SVG 作为背景图像?别误会,我爱内联 svg,因为图形/插图也有其语义,并且在 DOM 中为它们设置样式/应用行为非常棒!但对我来说,图标不属于此类。我宁愿使用链接,据我所知,您也可以在背景图像 url 中指定 SVG 片段 ID 对吧?这样,您可以为每个状态使用不同的片段,并且仅使用 CSS 来指示图标链接的外观。
干杯
Gion
为什么不在 “元素上使用类?
示例代码
http://codepen.io/lemnis/pen/hojcz
嗨,Lisa,
那也可能是一种方法……只是想到了一些东西 :-)
我最近一直专注于仅使用悬停和显示属性,以至于我从未意识到您也可以使用 Javascript 和路径来实现这一点。谢谢你的提示!
非常感谢 Chris 的贡献。我很想知道这是否也适用于外部 svg 和资源。
嗨,
我对如何在 svg 作为背景的情况下使用它有点困惑。我认为在这种情况下 css 不会起作用?
您(或任何人)能否提供一个快速示例?谢谢
在这个例子中,我不明白为什么不在一个 SVG 中有四个独立的路径并让它们旋转,但后来我试了一下,你无法引用 use 元素内部的内容。
http://codepen.io/mvaneijgen/pen/ybtcu
有没有什么解决方法?我真的很想这样设计一个菜单按钮
http://codepen.io/mvaneijgen/pen/ybtcu
并在打开或关闭菜单时更改其形状。
http://codepen.io/mvaneijgen/pen/GLEKq
我发现使用 HTML 中的 CSS 切换源效果很好。如果您有转换属性,它甚至会从一种状态平滑过渡到另一种状态。