如何同时使用多个CSS滤镜?

121

我正在尝试使用CSS滤镜。

我想同时使用模糊和灰度,但似乎无法在同一张图片上同时使用两种效果?

请查看此处的fiddle...

http://jsfiddle.net/joshmoto/fw0m9fzu/1/

.blur {
    filter: blur(5px);
    -webkit-filter: blur(5px);
    -moz-filter: blur(5px);
    -o-filter: blur(5px);
    -ms-filter: blur(5px);
}

.grayscale {
    filter: grayscale(1);
    -webkit-filter: grayscale(1);
    -moz-filter: grayscale(1);
    -o-filter: grayscale(1);
    -ms-filter: grayscale(1);
}


.blur-grayscale {
    filter: blur(5px) grayscale(1);
    -webkit-filter: blur(5px) grayscale(1);
    -moz-filter: blur(5px) grayscale(1);
    -o-filter: blur(5px) grayscale(1);
    -ms-filter: blur(5px) grayscale(1);
}

抱歉,我刚测试了一下,现在它们都可以工作了。请查看更新的代码片段。谢谢。 - joshmoto
1
你应该将其写在自己的答案中,然后接受该答案,而不是编辑您的问题。 - René
4个回答

187

由于它是一个名为filter的属性,每次添加样式时都会覆盖它。

CSS版本1

幸运的是,你可以在某些属性(如background-image和filter)中添加多个样式!要使其正常工作,您需要将所有过滤器样式放在一个以空格分隔的过滤器属性中。

.grayscale.blur {
    filter: blur(5px) grayscale(1);
}

CSS版本2

另一种灵活的替代方案是有意地创建一个"div soup"并在HTML堆栈中设置不同的过滤器。 例如:

<div class='demo__blurwrap' style='filter: blur(5px);'>
    <div class="demo__graywrap" style='filter: grayscale(1);'>
        <img src="awesome_image.jpeg" alt="">
    </div>
</div>

CSS版本 3

编辑:刚刚意识到我只是用变换写了这个版本,但是相同的思路适用。

另一个解决方案是CSS变量。我不会说它是理想的,但它是一个不错的实验。主要缺点是你需要声明很多变量,transform需要默认的长规则,并且嵌套变换肯定会出问题。

// Added just for fun
setInterval(() => {
  yes_this_works_and_one_of_many_reasons_ids_are_bad.classList.toggle('translate');
}, 1000);
setInterval(() => {
  yes_this_works_and_one_of_many_reasons_ids_are_bad.classList.toggle('scale');
}, 1500);
:root {
  --scale: 1;
  --translate: 0px;
}
.box {
  background: blue;
  width: 20px;
  height: 20px;
  transform: 
    scale(var(--scale))
    translate(var(--translate), var(--translate));
  transition: transform .3s;
}
.box.translate {
  --translate: 20px;
}
.box.scale {
  --scale: 3;
}
<div 
  id='yes_this_works_and_one_of_many_reasons_ids_are_bad' 
  class='box scale translate'
></div>

Javascript

如果您使用JavaScript来呈现样式,可以使用getComputedStyle读取当前应用的过滤器,并添加更多内容。

还有一篇相关文章 - 这更适用于动画,许多浏览器尚未支持:Additive animations

另外一篇关于 css-tricks 的相关文章:Houdini


1
是的,我喜欢你的“也许在未来”的建议,那将是理想的。 - MSC
转换方面也是一样的,那就太好了 :) - yunzen
这个“可能在未来”部分基于什么?它来自任何提议的规范添加吗?任何专有实现?还是只是一节不相关的沉思? - Jimbo Jonny
@JimboJonny,自我回答以来已经很长时间了。如果我没记错的话,我在某个CSS工作组邮件列表中看到了这个建议。但这可能更接近于“不相关的沉思”。 - René
为什么像transform这样的属性是用逗号分隔的,而filter却用空格分隔,这很令人困惑。 - Elijah Mock
通常的区别在于它是一个实际的列表(例如多个背景图像和变换),还是一个接受实际值集的属性,例如 margin: 0 1px 3px 0;。对于 background,两者都可以组合使用。仅使用空格将无法正常工作。此外,为了更容易记住,列表通常不限数量和顺序,而值集是预定义的。 - René

8

我正在尝试使用原生CSS创建实用类,这很有帮助,但看起来无法通过这种方式实现。

<img class="brightness-20 image-grayscale-100">
.brightness-20 {
    filter:brightness(20%);
}
.image-grayscale-100 {
    filter: grayscale(100%);
}

我不确定为什么他们不创建一个更具体的属性,比如:

filter-brightness: 20%; filter-grayscale: 100%

经过更多的工作,我提出了这个解决方案:

/*Initalize Variables No Adjustments*/
:root {
    --blur:0px;
    --contrast:100%;
    --brightness:100%;
    --contrast:100%;
    --dropshadow:0px 0px 0px black;
    --grayscale:0%;
    --hue-rotate:0deg;
    --invert:0%;
    --opacity:100%;
    --saturate:100%;
    --sepia:0%;
}
/*Apply Defult Variables To Image*/
.filter {
    filter: blur(var(--blur)) contrast(var(--contrast)) brightness(var(--brightness)) contrast(var(--contrast)) drop-shadow(var(--dropshadow)) grayscale(var(--grayscale)) hue-rotate(var(--hue-rotate)) invert(var(--invert)) opacity(var(--opacity)) saturate(var(--saturate)) sepia(var(--sepia)); 
}
/*Override Defults*/
.brightness-20 {
    --brightness:20%;
}
.image-grayscale-100 {
    --grayscale: 100%;
}

6

由于这似乎在答案中缺失,只在评论中提到,这里是有效的方法:

只需将多个过滤器以空格分隔组合即可,例如:

filter: grayscale() blur(5px);

此外,也可以查看这里


2
我正在使用这个。
/* Multiple filters */
backdrop-filter: url(filters.svg#filter) blur(4px) saturate(150%);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接