跳到正文

SVG 转 CSS 数据 URI

SVG to CSS Data URI

把 SVG 编码成可用作 CSS 背景的 data URI,只转义非转义不可的字符,把体积压到最小。

把 SVG 变成可以粘进样式表的数据 URI,用 URL 编码而不是 Base64,因为前者既更小又仍然可读。它并排显示三种大小,渲染编码后的 URI 让你看到它管用,并对那几样会让 SVG 一变成数据 URI 就渲染成空白的东西发出警告。

🔒 完全在你的浏览器里运行svgcssdata-uriencode

放一个 SVG 进来

也可以直接在下面改。

SVG

预览

是直接用编码后的 URI 画的,所以这里看得到,样式表里就看得到。

大小

原始 SVG

165 B

URL 编码

198 B

Base64

246 B

这里 URL 编码比 Base64 小 19.5%。

Base64 不管输入是什么都要多付 33⅓%。SVG 是文本,在 CSS 的 url() 里需要转义的字符只有几个——所以 URL 编码通常只比原文件大 10% 左右。而且它在样式表里还读得懂、grep 得到、diff 得出来,Base64 做不到。

输出

属性

只有 %, <, >, # 和几个括号字符会被转义;SVG 里的双引号会换成单引号,这样 CSS 字符串就能放心用双引号。最要紧的是 #:在 fill="#fff" 里不转义的话,它会开始一个片段标识符、把 URL 截断,于是什么都画不出来,而且任何地方都不报错。

想要位图的话,SVG 转 PNG 可以按任意倍数渲染成 PNG。想在编码之前把 SVG 变小,SVG 优化压缩 会重写路径数据。

怎么用

  1. 粘贴或拖入 SVG

    源码框可以编辑,所以你可以在这里修标记,不用回到文件。示例是一个描边图标,这是常见情况。

  2. 先读警告

    缺 `xmlns` 是抓住每个人的那一个:在 HTML 里内联时无所谓,但数据 URI 作为独立的 XML 文档解析,没有它浏览器什么都不渲染,也什么都不报。其他警告覆盖外部图片、脚本和没有 viewBox 的百分比尺寸。

  3. 检查预览

    它是从编码后的 URI 本身画的,不是从源码,所以如果图标出现在那个框里,它就会出现在你的样式表里。空框意味着 URI 坏了,上面的警告通常会说明原因。

  4. 选属性并复制

    声明随属性改变:`background-image`、`mask-image`、`content` 或者一个裸的 `src`。Base64 对少数接受不了百分号编码 URI 的消费者可用,而且它总是更大。

常见问题

为什么不用 Base64?大家都用 Base64。

Base64 对任何输入都固定多花 33⅓%,因为它把三个字节变成四个。SVG 是文本,在 CSS 的 `url()` 里实际需要转义的只有 `%`、`<`、`>`、`#` 和两三个括号,所以 URL 编码通常落在比原文件大 10% 左右。它在样式表里也仍然可以 grep、可以 diff。面板会为你的文件打印两个数字。

我的图标消失了,哪里都没有报错。

几乎总是一个没转义的 `#`。在 `fill="#fff"` 里,井号开启一个片段标识符,所以 URL 在那里被截断,浏览器去抓取一个不是 SVG 的东西——不出声。这个编码器会转义它。如果你是手写的 URI,这是第一个要查的。

能在数据 URI 里给 SVG 做动画或脚本吗?

作为 CSS 背景不能。那样加载的 SVG 运行在受限的静态模式:没有脚本、没有 `foreignObject`、没有外部资源,外层页面的 CSS 也进不去。声明式的 SMIL 动画有时运行有时不运行,取决于引擎。需要其中任何一样,改把 SVG 内联进文档。

什么时候数据 URI 是错误的选择?

当 SVG 很大或者用在不止两三个地方时。数据 URI 无法单独缓存,所以每个带这份样式表的页面都再带一次图标,一个内联在 CSS 里的 30KB 插图就是关键路径上的 30KB。小图标和图案是它的用武之地;更大的东西作为文件或者雪碧图更好。

可以从这些接进来

接下来

这些工具吃得下当前工具的产出,结果可以直接送过去。