SVG 转 CSS - 一条真正能用的 background-image
把 SVG 粘进样式表会以两种特定方式失败,而且两种都是静默的。转义弄错了,填充颜色里一个未编码的井号就会把 URL 截断,于是规则解析正常,图片却根本不出现。图稿里用了 currentColor,那么它一旦变成 data URI 就不再随之改色,因为这个 URI 是一份独立的文档,没有任何东西可以继承。这个工具替你处理前一件事,并就后一件事提醒你,给你一条可以原样粘贴的 background-image 声明。它使用 URL 编码形式而不是 base64,对 SVG 来说前者既更小也更易压缩。一切都在你的设备上运行,并且在产出任何内容之前会先净化文件。
如何使用此工具
放入你的 SVG
把文件拖到上方方框里或点击选择。在生成任何内容之前,脚本、事件处理器和指向文档之外的引用都会被移除,面板会列出它删掉了什么。
复制 background-image 规则
第一段代码片段是一条完整的声明,其中的 data URI 已经转义并加好引号 - 直接粘进一条规则即可。下面还有一个 base64 版本,供那些非它不可的流水线使用,两者的字节数都会显示出来。
查看 currentColor 警告
如果你的图稿使用了 currentColor,会出现一条提示,说明它为什么会渲染成黑色,并改为提供一段 mask-image 代码。那段代码用元素自身的文字颜色来绘制这个形状,是最接近的可行等价方案。
补上你需要的尺寸属性
单独一条 background-image 会按图稿的固有尺寸平铺。加上 background-size 和 background-repeat: no-repeat 来控制它,或者直接用那段 mask 代码,它已经把两者都包含在内了。
常见问题
哪些字符必须转义?
五个,外加换行。百分号必须最先处理,否则它会把转义本身再转义一遍。然后是井号,否则它会开启一个 URL 片段,把你第一个十六进制颜色之后的内容全部截断。再然后是会从 HTML 属性中逃逸出去的尖括号,以及包裹整个值的双引号。
我的 background-image 就是不出现,为什么?
几乎总是因为一个未转义的井号。未转义的 data URI 里一个 #c33 填充会让 URL 在井号处结束,于是浏览器请求了一份被截断的文档,得不到任何可用内容,什么也不显示 - 而且控制台没有报错,因为在 CSS 看来这条规则完全合法。
为什么 currentColor 在 data URI 里失效了?
因为 data URI 是一份独立的文档。currentColor 是相对于 SVG 所在元素计算出的 color 来解析的,而作为图片加载的 SVG 根本没有这样一个元素 - 它不属于你页面的文档树。于是它回退到初始值,也就是黑色。
mask-image 这个变通办法是什么?
就是把 SVG 当作模板而不是当作图片来用。把 background-color 设为 currentColor,让元素以继承来的文字颜色着色,再用 mask-image 加载你的 data URI,这样只有图稿的形状会透出来。记得为 Safari 一并加上 -webkit-mask-image。
在 CSS 里我该改用 base64 吗?
很少需要。base64 会让同一张图在样式表里大出约五分之一,而且压缩效果差得多,因为它在 gzip 眼里像噪声。只有当构建工具或 CMS 拒绝百分号编码形式时才值得动用它,这也是本页两种都提供的原因。
我能用单引号包裹 url() 的值吗?
用这里的输出不行,而且这是刻意的。SVG 内部的属性定界符已经被改成了单引号以避免转义,体积的节省大部分正来自于此。这就使得双引号成为唯一安全的包裹符 - 一个单引号会让整个值提前结束。
这在 CSS 自定义属性里能用吗?
能。把整个 url("…") 值赋给一个自定义属性,再在需要的地方引用它,这是把一长串 data URI 从规则中间挪走的整洁办法。自定义属性把值当作一串记号来接收,所以这里的转义本来就是正确的。
对样式表来说多大算太大?
大约 4 KB 的 SVG 源码,面板正是在那里提醒你。CSS 里的 data URI 会被每一位加载该样式表的访客下载,无论那条规则是否真的匹配到元素,而且它无法被单独缓存。低于这个阈值它通常胜过多一次请求;高于这个阈值通常就不再划算。
我能把一整张插画放进样式表吗?
能,但你多半不该这么做。插画动辄几十 KB,而这些字节的每一个,都会被每一位加载该样式表的人下载,无论那条规则是否真的生效。data URI 是给图标和小型装饰形状用的;任何有真正细节的东西,都该待在它自己的文件里。
浏览器会缓存内联进来的图片吗?
只会作为承载它的那份样式表的一部分被缓存,这就是这笔交易的内容。没有独立的缓存条目,也没有独立的请求,所以首次访问更快,而样式表此后的任何改动都会连带把图片一起重新下载。对一个每页都用到的图标来说,这通常很划算。
有任何东西被发送到服务器吗?
没有。转义完全在你的浏览器里运行,所以文件不会离开你的设备,不会被存储,我们也永远看不到它。这也意味着没有什么可等待的,也不存在排队 - 你放入文件的那一刻,所有代码片段就已经生成好了。
您可能还需要
有问题吗? 报告问题