在 :before 或 :after CSS 中更改 SVG 填充颜色

Posted

技术标签:

【中文标题】在 :before 或 :after CSS 中更改 SVG 填充颜色【英文标题】:Change SVG fill color in :before or :after CSS 【发布时间】:2014-02-25 21:55:16 【问题描述】:

我有一个这样的 SVG 图形:

a::before  content: url(filename.svg); 

当我将鼠标悬停在标签上时,我真的希望 SVG 改变填充颜色,而不像现在这样加载新的 SVG 文件:

a:hover::before  content: url(filename_white.svg); 

这是否可以使用 javascript、jQuery 或我不知道的纯 CSS 来实现?

谢谢。

【问题讨论】:

无法通过 JavaScript 处理 :before 和/或 :after 伪元素。它们不存在于 DOM 中。 不确定,但也许this 会帮助你 【参考方案1】:

接受的答案是不正确的,这实际上可以通过使用 SVG 蒙版 和背景颜色的解决方法来实现:

p:after 
  width: 48px;
  height: 48px;
  display: inline-block;
  content: '';
  -webkit-mask: url(https://mmathys.github.io/heart.svg) no-repeat 50% 50%;
  mask: url(https://mmathys.github.io/heart.svg) no-repeat 50% 50%;
  -webkit-mask-size: cover;
  mask-size: cover;


.red:after 
  background-color: red;


.green:after 
  background-color: green;


.blue:after 
  background-color: blue;
<p class="red">red heart</p>
<p class="green">green heart</p>
<p class="blue">blue heart</p>

您实际上并没有修改 SVG DOM 本身,您只是更改了背景颜色。这样,您甚至可以使用图像或渐变作为背景。


更新

正如 MisterJ 所说,this feature is sadly not widely supported.

六年后,对前缀使用的支持已经上升到97%。

【讨论】:

我认为您应该更新以支持此方法 (caniuse.com/#feat=css-masks) 如果您想使用此方法,您需要放弃一些浏览器。 实际上甚至低于 88%。浏览器中的部分支持不支持您正在使用的功能。例如 Firefox 不支持它。 效果很好,您可以回退到内容属性中的 Unicode 符号(或使用 fontawesome) content:'' 似乎没有必要。 @coops 很高兴我能帮助到别人 :)【参考方案2】:

一种类似于@lmaooooo's answer 的技术,无需设置display: inline-block。当您想要保留 display: inline 以确保 :after 内容不会换行到独立于前面的文本内容的新行时,这在对内容进行分句时很有用。

还使用 clip-path 来防止背景颜色在 Safari 中泄漏(其用途取决于图像/行高/等)。

a[target="_blank"]:after 
  background-color: currentColor;
  content: "";
  padding: 0 0.5em;
  margin: 0 0.125rem;
  -webkit-mask-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 2048 2048'%3E%3Cpath d='M1792 256v640h-128V475l-851 850-90-90 850-851h-421V256h640zm-512 1007h128v529H256V640h529v128H384v896h896v-401z'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 2048 2048'%3E%3Cpath d='M1792 256v640h-128V475l-851 850-90-90 850-851h-421V256h640zm-512 1007h128v529H256V640h529v128H384v896h896v-401z'/%3E%3C/svg%3E");
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  clip-path: padding-box inset(0.28125em 0);
Lorem ipsum sumit dolar &lt;a href="#" target="_blank"&gt;hello world&lt;/a&gt;

【讨论】:

【参考方案3】:

使用content 属性生成(非公开)标记,其功能等同于 元素中的 svg。

您不能将样式应用于 svg 文档中的元素,因为:

    样式不允许跨文档级联 当使用 (或content,或任何引用 svg 的 css 图像属性)时,出于安全考虑,浏览器不会公开 svg 文档

类似的问题,但针对 background-image here 和 here。

所以,要做你想做的事,你必须以某种方式绕过上述两点。有多种选择,例如使用内联 svg、使用过滤器(应用于 )或生成不同的 svg 文件(或数据 URI),如您的问题所示。

【讨论】:

以上是关于在 :before 或 :after CSS 中更改 SVG 填充颜色的主要内容,如果未能解决你的问题,请参考以下文章

css3 转换:切换 css 类不会转换顶部/左侧/底部/右侧(由于添加了 :before 或 :after 元素)[重复]

CSS:使用带有 css 伪类的图像精灵 :before 和 :after

css 旋转一个伪 :after 或 :before 内容:""

在 ::after 或 ::before 伪元素内容中添加换行符

css 使用parent伪元素垂直对齐内联块元素:before或:after。无论父母身高还是身高都无所谓

::before和::after伪元素的用法