跳到正文
SvgJsx
语言: 中文

让 SVG 图标使用 currentColor

把写死的 fill 和 stroke 颜色替换为 currentColor,让图标自动继承父元素的文字颜色、在悬停时变色,并适配深色模式。

快速预设:
将 .svg 文件拖放到这里,或文件通过 FileReader 在本地读取,绝不会上传。
选项
导出方式:
import type { SVGProps } from "react";

const HeartIcon = ({ size = 24, ...props }: SVGProps<SVGSVGElement> & { size?: number | string }) => (
  <svg viewBox="0 0 24 24" className="icon icon-heart" width={size} height={size} {...props}>
    <g id="Layer_1" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M19.0001 14.0002c1.4900-1.4600 3.0000-3.2100 3.0000-5.5000A5.5000 5.5000 0 0 0 16.5000 3c-1.7600 0-3.0000.5000-4.5000 2-1.5000-1.5000-2.7400-2-4.5000-2A5.5000 5.5000 0 0 0 2 8.5000c0 2.3000 1.5000 4.0500 3 5.5000l7 7Z" style={{ fillOpacity: "0.15", fill: "currentColor" }} />
    </g>
  </svg>
);

export default HeartIcon;

预览

转换后 SVG 的预览
原始 SVG
706 B
优化后 SVG
548 B(-22%)
组件
692 B

currentColor 的作用

currentColor 是一个 CSS 关键字,它会解析为元素计算后的 color 值。当 SVG 使用 fill="currentColor" 时,图标会使用父元素的颜色来绘制,无论这个颜色来自 Tailwind 类、链接的悬停状态还是深色模式媒体查询。

设计工具导出的图标通常带有固定的十六进制颜色,例如 fill="#111827"。这会把图标锁定为一种颜色,迫使你为每个主题维护不同的文件。转换为 currentColor 后,一个文件就能适用于任何场景。

转换器会改动哪些内容

开启 currentColor 选项后:

  • 带颜色值的 fill 和 stroke 属性会变为 currentColor。
  • 内联 style 属性中的 fill 和 stroke 也会被替换。
  • none、transparent、inherit 以及 url(#gradient) 引用会被保留,因此描边轮廓和渐变仍然正常。
  • 渐变中的 stop-color 等其他颜色保持不变。

什么时候不该用 currentColor

多色插画、品牌 Logo 和旗帜依赖多种特定颜色,把它们全部替换成同一种颜色会让作品变得扁平。对于这类文件,请保留原始颜色,或者只对需要随主题变化的少数颜色使用 CSS 自定义属性。

常见问题

为什么转换后图标变成了黑色?

currentColor 继承的是 CSS 的 color 属性。如果父元素没有设置颜色,浏览器默认使用黑色。请在图标或其父元素上设置颜色,例如 class="text-blue-600"。

currentColor 对描边有效吗?

有效。fill 和 stroke 都接受 currentColor,这也是 Lucide、Heroicons 等线性图标库使用 stroke="currentColor" 的原因。

可以在 <img> 标签中使用 currentColor 吗?

不行。通过 <img> 或 CSS background-image 加载的 SVG 与页面 CSS 是隔离的,currentColor 会被解析为黑色。SVG 必须内联,而组件正好可以做到这一点。

渐变还能正常工作吗?

能。使用 url(#id) 引用渐变的填充不会被改动,而且即使开启了移除 id,被引用的 id 也会保留。