替换 SVG 图标

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

假设您正在使用内联 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 可以很好地处理这种情况。