修改SVG填充颜色:在CSS之前或之后

时间:2022-11-20 22:56:32

I have a SVG graphic put like this:

我有一个像这样的SVG图形:

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

When I hover over the tag, I really want the SVG to change the fill color, without loading a new SVG file, as I have now:

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

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

Is this possible to achieve using JavaScript, jQuery or just pure CSS that I am not aware of?

使用JavaScript、jQuery或我不知道的纯CSS实现这一点可能吗?

Thanks.

谢谢。

2 个解决方案

#1


12  

Using the content property generates (non-exposed) markup functionally equvialent to an svg in an <img> element.

修改SVG填充颜色:在CSS之前或之后元素中,使用内容属性生成(非公开的)标记功能与svg的功能相同。

You cannot apply style to elements inside the svg document because:

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

  1. styles are not allowed to cascade across documents
  2. 样式不允许跨文档级联
  3. when using <img> (or content, or any css image property that references svg) the svg document is not exposed by the browsers due to security concerns
  4. 当使用修改SVG填充颜色:在CSS之前或之后(或内容,或任何引用svg的css图像属性)时,出于安全考虑,浏览器不会公开svg文档

Similar questions, but for background-image here and here.

类似的问题,但在这里和这里的背景图像。

So, to do what you want you must get around the two points above somehow. There are various options for doing that, e.g using inline svg, using filters (applied to the <img>) or generating different svg files (or data URIs), as in your question.

所以,要想做你想做的,你必须绕过上面的两点。这样做有很多选择,e。g使用内联svg、使用过滤器(应用于修改SVG填充颜色:在CSS之前或之后)或生成不同的svg文件(或数据uri),如您的问题。

#2


17  

The accepted answer is incorrect, this is actually possible by applying a workaround with an SVG mask and background-color:

所接受的答案是不正确的,实际上可以通过使用SVG蒙版和背景色进行变通:

p:after {
  width: 48px;
  height: 48px;
  display: inline-block;
  content: '';
  -webkit-mask: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/18515/heart.svg) no-repeat 50% 50%;
  mask: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/18515/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>

You're not actually modifying the SVG DOM itself, you're just changing the background color. That way, you could even use images or gradients as background.

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


Update

As MisterJ mentioned, this feature is sadly not widely supported.

正如MisterJ所提到的,不幸的是,这个特性并没有得到广泛的支持。

After three years, the support for prefixed use has risen to 89%.

三年后,对预置使用的支持上升到89%。

#1


12  

Using the content property generates (non-exposed) markup functionally equvialent to an svg in an <img> element.

修改SVG填充颜色:在CSS之前或之后元素中,使用内容属性生成(非公开的)标记功能与svg的功能相同。

You cannot apply style to elements inside the svg document because:

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

  1. styles are not allowed to cascade across documents
  2. 样式不允许跨文档级联
  3. when using <img> (or content, or any css image property that references svg) the svg document is not exposed by the browsers due to security concerns
  4. 当使用修改SVG填充颜色:在CSS之前或之后(或内容,或任何引用svg的css图像属性)时,出于安全考虑,浏览器不会公开svg文档

Similar questions, but for background-image here and here.

类似的问题,但在这里和这里的背景图像。

So, to do what you want you must get around the two points above somehow. There are various options for doing that, e.g using inline svg, using filters (applied to the <img>) or generating different svg files (or data URIs), as in your question.

所以,要想做你想做的,你必须绕过上面的两点。这样做有很多选择,e。g使用内联svg、使用过滤器(应用于修改SVG填充颜色:在CSS之前或之后)或生成不同的svg文件(或数据uri),如您的问题。

#2


17  

The accepted answer is incorrect, this is actually possible by applying a workaround with an SVG mask and background-color:

所接受的答案是不正确的,实际上可以通过使用SVG蒙版和背景色进行变通:

p:after {
  width: 48px;
  height: 48px;
  display: inline-block;
  content: '';
  -webkit-mask: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/18515/heart.svg) no-repeat 50% 50%;
  mask: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/18515/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>

You're not actually modifying the SVG DOM itself, you're just changing the background color. That way, you could even use images or gradients as background.

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


Update

As MisterJ mentioned, this feature is sadly not widely supported.

正如MisterJ所提到的,不幸的是,这个特性并没有得到广泛的支持。

After three years, the support for prefixed use has risen to 89%.

三年后,对预置使用的支持上升到89%。