Use Multiple CSS Filters at the Same Time

use multiple css filters at the same time?

Because it's one property named filter, every time you want to add a style to it you override it.

CSS version 1

Fortunately you can add multiple styles in some properties like background-image and filter!
To get this working you'll have to put all the filter styles in one space separated filter property.

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

CSS version 2

An alternative, flexible, solution would be to create a "div soup" on purpose and set different filters in the html stack.
e.g.

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

CSS version 3

edit: just realised I just wrote this version with transforms, but the same idea applies.

Yet another solution is CSS vars. I wouldn't say it's ideal but it's a nice experiment. The major downside is that you need to declare a lot of variables, have default long rules for transform and nested transforms will definitely break.

// 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>

Apply multiple css filters dynamically

Here you go. https://jsfiddle.net/2p8kwjv1/1/

Apparently if you want multiple filters you have to define them in the same filter definition. like so

img{
filter: blur(50px) sepia(50%);
-webkit-filter: blur(50px) sepia(50%);
}

So to achieve this in javascript you have to keep references to these values. Then every time you change the sepia, you can also apply the current blur value to display two filters at the same time, dynamically.

var sepia = slider1.value;
var blur = slider2.value;

slider1.addEventListener("input", function(){
sepia = this.value;
img.style["-webkit-filter"] = "blur("+blur+"px) sepia(" + this.value + "%)";
});
slider2.addEventListener("input", function(){
blur = this.value;
img.style["-webkit-filter"] = "blur(" + this.value + "px) sepia("+sepia+"%)" ;
});

Apply two CSS classes which contain `filter` to an HTML element

.bbb filter override .aaa filter. This is the way CSS works, it's override precedent attributes.
If you want to apply both filter, use one class with:

.aaa {
filter: grayscale(100%) drop-shadow(10px 10px 10px black);
}

Multiple filter transition

To make it easier to see the effect, I have created a new snippet, where the color of the image is instead a background.

But it will work the same for your use case.

Just change the filters that you are applying

.test {

width: 200px;

height: 150px;

background: cyan;

margin: 20px;

transition: filter 4s;

}

.test:hover {

filter: grayscale(1) brightness(1.5);

}
<div class="test"></div>

Apply three CSS filters side by side on an image?

EDIT: I see someone posted an answer already but I'll just post mine since I did it a little differently.

If you want to have them sectioned off correctly, you are going to need to split it up into different elements for each filter. You'll also need to have each element have its own background set so the filter can apply to its own section of the image and you'll need to set the position accordingly (you don't have to worry about requests because it'll only request the background image once).

Also the reason in yours the first section wasn't 1/3 is because you set it to 30% when 1/3 is technically 33.33% (repeating of course).

I made a codepen here.

.container {

position: relative;

width: 900px;

height: 300px;

}

.filter-section {

float: left;

width: 33.333333333%;

height: 100%;

background: url(http://lorempixel.com/900/300) no-repeat;

}



.grayscale {

-webkit-filter: grayscale(1);

filter: grayscale(1);

background-position: left;

}

.sepia {

-webkit-filter: sepia(1);

filter: sepia(1);

background-position: center;

}

.contrast {

-webkit-filter: contrast(200%);

filter: contrast(200%);

background-position: right;

}
<div class="container">

<div class="grayscale filter-section"></div>

<div class="sepia filter-section"></div>

<div class="contrast filter-section"></div>

</div>

Where in the CSS specs does it say how multiple properties with the same name should be handled?

To answer my own question – I realised I should probably look for the answers to the two sub-questions "which out of two declarations wins" and "what should it do about invalid declarations".

For the former, https://www.w3.org/TR/css-cascade-3/#cascade-order says

The last declaration in document order wins.

which I take to mean that out of two property-value declarations with the same property, the last one wins.

And for the latter, https://www.w3.org/TR/css-cascade-3/#w3c-partial says

user agents must not selectively ignore unsupported component values and honor supported values in a single multi-value property declaration: if any value is considered invalid (as unsupported values must be), CSS requires that the entire declaration be ignored.

which I take to mean that if a browser e.g. doesn't support image-set in the question's example, it will ignore that entire declaration.



Related Topics



Leave a reply



Submit