我有一个图标,我想使用 CSS 更改其颜色。它位于 CSS 内联的数据 URI 优化 SVG 中。
通常,这是不可能的。这就是发明图标字体的原因;与 SVG 相比,它们的主要优势是能够从 CSS 接收 color
和 text-shadow
规则。嗯,CSS filters现在能够对任意图像执行这两种操作,并且 they now work in all Blink, Webkit and Gecko browsers , 和 can be expected for future IE/Spartan .
text-shadow
替换很容易;只需使用 drop-shadow
filter .
然而,尽管所有必要的滤镜都已准备就绪,但事实证明,将图像着色为特定颜色非常棘手。到目前为止,我的理论如下:
- 使用
contrast(0)
将整个图像变成纯灰色,同时保持 alpha channel (Mozilla wiki 说它会变成黑色,但在所有浏览器中它变成灰色,一定是打字错误)。 - 使用
sepia(1)
,因为我们不能对灰度图像的色相/饱和度进行操作。这确保了整个图像由我们可以进行数学运算的引用颜色组成;具体来说,#AC9977
。
此时,我们应该能够使用 hue-rotate
将整个图像从现在的纯色 #AC9977
变成我们想要的任何颜色。 , saturate
和 brightness
.
首先,浏览器使用什么颜色坐标?我找不到 the spec 的意义确定它是否使用 HSL (Lightness) or HSV (Value) , 但由于 HSB (Brightness) 是 HSV 的另一个名称,我想它使用的是 HSV。此外,使用诸如 brightness(999)
之类的东西会使颜色饱和(而不是使它们变白),这会发生在 HSV 而不是 HSL 中。
基于这个假设,我们将进行如下操作:
- 计算
#AC9977
和我们想要的颜色之间的色相差,并使用hue-rotate
. - 计算两者之间的饱和度差异,并使用
saturate
. - 计算两者之间的亮度差异,并使用
brightness
.
由于这不是手动完成的事情,我们将使用 LESS preprocessor :
.colorize(@color) {
@sepiaGrey: #AC9977;
@hOffset: (hsvhue(@color) - hsvhue(@sepiaGrey)) * 1deg;
@sRatio: unit(hsvsaturation(@color) / hsvsaturation(@sepiaGrey));
@vRatio: unit(hsvvalue(@color) / hsvvalue(@sepiaGrey));
-webkit-filter: contrast(0) sepia(1) hue-rotate(@hOffset) saturate(@sRatio) brightness(@vRatio);
filter: contrast(0) sepia(1) hue-rotate(@hOffset) saturate(@sRatio) brightness(@vRatio);
}
根据我的理解,这应该可行。 But it isn't . 为什么,以及如何让它发挥作用?
我想要达到的目标的例子
将图标视为图像或元素(背景图像、基于 CSS 的形状等),具有任何颜色,并具有由透明度定义的形状(不是 一个可以简单叠加的矩形图像)。我想让它完全由具有 CSS 的特定颜色组成(大概是使用 filters
)。
我计划将其实现为 LESS mixin这需要一个颜色参数,但只需指导 HSB 函数背后的逻辑就足够了。
最佳答案
我有时会尝试实现您想要的,但没有成功。
无论如何你有一个替代方案,使用混合模式:
div {
background-color: green;
mix-blend-mode: color;
position: absolute;
width: 200px;
height: 400px;
}
<div></div>
<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/a/a0/Hsl-hsv_models.svg/400px-Hsl-hsv_models.svg.png" height="400">
我错过了透明度要求。让我们再试一次 :-)。缺点:需要设置图片2次。
#test1 {
background: linear-gradient(red, red), url("http://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png");
width: 100%;
height: 500px;
background-blend-mode: hue;
-webkit-mask-image: url("http://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png");
}
body {
background-color: lightblue;
}
<div id="test1">
</div>
好的;假设想要的结果是:你有一个图像,它将充当一个面具。您想要使用此蒙版在现有图像上设置彩色叠加层,但您希望在 CSS 样式中指定颜色,以便轻松编辑。
如果您可以更改图像,以便使用的 channel 是亮度而不是 alpha,则以下示例可以作为您的解决方案 你需要一个灰色和黑色的滤镜,像这样
.test {
width: 200px;
height: 200px;
display: inline-block;
background-image: url(http://i.stack.imgur.com/kxKXy.png);
background-size: cover;
background-blend-mode: exclusion;
mix-blend-mode: hard-light;
}
.testred {
background-color: red;
}
.testblue {
background-color: blue;
}
body {
background: repeating-linear-gradient(45deg, lightblue 0px, lightyellow 50px);
}
<div class="test testred"></div>
<div class="test testblue"></div>
关于css - 使用 CSS 过滤器模拟 Photoshop 的 "Color Overlay"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29458666/