用作 base-64 背景图像数据时如何更改 svg 填充颜色?

Posted

技术标签:

【中文标题】用作 base-64 背景图像数据时如何更改 svg 填充颜色?【英文标题】:how to change svg fill color when used as base-64 background image data? 【发布时间】:2014-04-18 13:26:11 【问题描述】:

我在一个项目中使用 SVG,像这样在 css 中加载:

background-image: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20xmlns%3Axlink%3D%22http%3A//www.w3.org/1999/xlink%22%20version%3D%221.1%22%20x%3D%220px%22%20y%3D%220px%22%20width%3D%2222px%22%20height%3D%2238px%22%20viewBox%3D%220%200%2022%2038%22%20enable-background%3D%22new%200%200%2022%2038%22%20xml%3Aspace%3D%22preserve%22%3E%3Cstyle%3E.style0%7Bfill%3A%09%23f47216%3B%7D%3C/style%3E%3Cpath%20d%3D%22M2.643%2038c-0.64%200-1.282-0.231-1.79-0.699c-1.074-0.988-1.143-2.661-0.154-3.735l13.13-14.258L0.664%204.4%20c-0.967-1.094-0.865-2.765%200.229-3.732s2.765-0.864%203.7%200.229L19.37%2017.592c0.898%201%200.9%202.545-0.035%203.542L4.588%2037.1%20C4.067%2037.7%203.4%2038%202.6%2038z%22%20class%3D%22style0%22/%3E%3C/svg%3E');

我有一些悬停状态可以通过更改箭头的填充颜色来突出显示。

现在,我只是将相同的 svg 数据与填充部分(填充%3A%09%23f47216%3B%7D%3C,其中 f47216 是颜色)更改为右侧/新的颜色。效果很好。不过,我想知道是否还有其他更聪明的方法。

【问题讨论】:

如果您设置为您的 svg 内容使用 background-image / data uri,那么您这样做的方式是唯一可以让它工作的方法。背景图像被视为只是一个图像文件,您无法使用其他 CSS 样式更改它,就像您无法更改 PNG 或 JPEG 文件一样。 【参考方案1】:

使用 CSS 的 filter 属性。 对我来说,我想在悬停时将图标的颜色更改为白色:

filter: grayscale(1) brightness(2);

【讨论】:

这对我不起作用,但 filter: invert(1); 起作用了,仅供像我一样绝望的未来读者参考 ;-) filter: invert(1); 仅适用于黑色。您可以将filter: brightness(0) invert(1); 用于任何颜色。【参考方案2】:

或者如果你想动态尝试:

var green = '3CB54A';
var red = 'ED1F24';
var svg = '<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"    viewBox="0 0 320 100" enable-background="new 0 0 320 100" xml:space="preserve"> <polygon class="mystar" fill="#'+green+'" points="134.973,14.204 143.295,31.066 161.903,33.77 148.438,46.896 151.617,65.43 134.973,56.679 118.329,65.43 121.507,46.896 108.042,33.77 126.65,31.066 "/><circle class="mycircle" fill="#'+red+'" cx="202.028" cy="58.342" r="12.26"/></svg>';      
var encoded = window.btoa(svg);
document.body.style.background = "url(data:image/svg+xml;base64,"+encoded+")";

Fiddle Here

【讨论】:

非常有用的答案。【参考方案3】:

Base64 将是:

url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMjJweCIgaGVpZ2h0PSIzOHB4IiB2aWV3Qm94PSIwIDAgMjIgMzgiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDIyIDM4IiB4bWw6c3BhY2U9InByZXNlcnZlIj48c3R5bGU+LnN0eWxlMHtmaWxsOgkjZjQ3MjE2O308L3N0eWxlPjxwYXRoIGQ9Ik0yLjY0MyAzOGMtMC42NCAwLTEuMjgyLTAuMjMxLTEuNzktMC42OTljLTEuMDc0LTAuOTg4LTEuMTQzLTIuNjYxLTAuMTU0LTMuNzM1bDEzLjEzLTE0LjI1OEwwLjY2NCA0LjQgYy0wLjk2Ny0xLjA5NC0wLjg2NS0yLjc2NSAwLjIyOS0zLjczMnMyLjc2NS0wLjg2NCAzLjcgMC4yMjlMMTkuMzcgMTcuNTkyYzAuODk4IDEgMC45IDIuNTQ1LTAuMDM1IDMuNTQyTDQuNTg4IDM3LjEgQzQuMDY3IDM3LjcgMy40IDM4IDIuNiAzOHoiIGNsYXNzPSJzdHlsZTAiLz48L3N2Zz4=');

使用像http://www.base64encode.org/这样的工具

这并不能直接回答您的问题,但它确实让我们可以执行以下操作。我们现在可以测试一下:

.icon:hover .style0 
    fill: red;

将工作,或使用

.icon 
    background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMjJweCIgaGVpZ2h0PSIzOHB4IiB2aWV3Qm94PSIwIDAgMjIgMzgiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDIyIDM4IiB4bWw6c3BhY2U9InByZXNlcnZlIj48c3R5bGU+LnN0eWxlMHtmaWxsOgkjZjQ3MjE2O308L3N0eWxlPjxwYXRoIGQ9Ik0yLjY0MyAzOGMtMC42NCAwLTEuMjgyLTAuMjMxLTEuNzktMC42OTljLTEuMDc0LTAuOTg4LTEuMTQzLTIuNjYxLTAuMTU0LTMuNzM1bDEzLjEzLTE0LjI1OEwwLjY2NCA0LjQgYy0wLjk2Ny0xLjA5NC0wLjg2NS0yLjc2NSAwLjIyOS0zLjczMnMyLjc2NS0wLjg2NCAzLjcgMC4yMjlMMTkuMzcgMTcuNTkyYzAuODk4IDEgMC45IDIuNTQ1LTAuMDM1IDMuNTQyTDQuNTg4IDM3LjEgQzQuMDY3IDM3LjcgMy40IDM4IDIuNiAzOHoiIGNsYXNzPSJzdHlsZTAiLz48L3N2Zz4=');
    height: 40px;
    width: 40px;


.icon:hover 
    background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMjJweCIgaGVpZ2h0PSIzOHB4IiB2aWV3Qm94PSIwIDAgMjIgMzgiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDIyIDM4IiB4bWw6c3BhY2U9InByZXNlcnZlIj48c3R5bGU+LnN0eWxlMHtmaWxsOglyZWQ7fTwvc3R5bGU+PHBhdGggZD0iTTIuNjQzIDM4Yy0wLjY0IDAtMS4yODItMC4yMzEtMS43OS0wLjY5OWMtMS4wNzQtMC45ODgtMS4xNDMtMi42NjEtMC4xNTQtMy43MzVsMTMuMTMtMTQuMjU4TDAuNjY0IDQuNCBjLTAuOTY3LTEuMDk0LTAuODY1LTIuNzY1IDAuMjI5LTMuNzMyczIuNzY1LTAuODY0IDMuNyAwLjIyOUwxOS4zNyAxNy41OTJjMC44OTggMSAwLjkgMi41NDUtMC4wMzUgMy41NDJMNC41ODggMzcuMSBDNC4wNjcgMzcuNyAzLjQgMzggMi42IDM4eiIgY2xhc3M9InN0eWxlMCIvPjwvc3ZnPg==');

这对我来说似乎效率低下,因为当我们想要更改的只是颜色时,我们不得不为悬停复制许多相同的信息。

working example

【讨论】:

可能值得一看:***.com/questions/7360723/… 虽然不是很准确,但这可能很有用:css-tricks.com/svg-sprites-use-better-icon-fonts 好吧,不,不可能使用 style0,因为最终的 svg 数据中没有 style0。所以我想我的方式是唯一可能的。也许它并没有真正优化,但 http 请求是,所以对我来说已经足够了。 为了更好地解释:我首先使用 this site 清理我的 svg。这里还有你正在写的 style0 类。但随后我会将优化的 svg 转换为 this site 中的 base-64,然后将 style0 剥离。 这种低效会被gzip或brotli有效压缩【参考方案4】:

我想发布我自己问题的答案。没有确切的答案,因为它并不意味着 svg 作为背景和 base64,但这是我目前的替代方式,如果你只需要单色图标更有效:只需使用 svg 作为 css 蒙版,并更改背景颜色。然后,您还可以在鼠标事件上应用过渡。我的意思是这样的:

mask-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"   xml:space="preserve"><path d="M11.432 9.512a.636.636 0 0 1 0 .918L2.12 19.742a.636.636 0 0 1-.458.201.637.637 0 0 1-.46-.201l-1-.998C.068 18.609 0 18.459 0 18.285s.068-.329.199-.461l7.854-7.852L.199 2.118A.638.638 0 0 1 0 1.66c0-.174.068-.327.199-.46l1-.998A.634.634 0 0 1 1.66 0c.172 0 .325.068.458.201l9.314 9.311z"/></svg>');
mask-size: auto 12px;
mask-repeat: no-repeat;
transition: background-color 200ms;
background-color: #ff0000;

更多代码和演示请看这个小提琴:

https://jsfiddle.net/o25beLqj/

还要注意几点:

mask-image 内部没有 base64 代码。前面只是data:image/svg+xml;utf8,

mask css 属性与 css 背景属性几乎相同,看看文档,你会发现你可以做很多事情,它们可以在各种用例中替换背景图像

【讨论】:

以上是关于用作 base-64 背景图像数据时如何更改 svg 填充颜色?的主要内容,如果未能解决你的问题,请参考以下文章

用作背景图像的 SVG 会丢失嵌入图像?

将图像数据URI(base64)设置为画布背景

如何使用 javascript 获取 base64 编码图像的地址

Base64 图像不会使用任何常用方法缩小

用作背景图像时如何缩放 CSS 精灵?

如何使用 C# 将数据库中的 base64 值转换为流