use multiple css filters at the same time?

I am experimenting with css filters.

And I would like use the blur and grayscale at the same time, but I can't seem to use both simultaneously on the same image?

See fiddle here...

.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);
}
2

3 Answers

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 style='filter: grayscale(1);'> <img src="awesome_image.jpeg" alt=""> </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>

Javascript

Lastly, if you were to use JavaScript to render the styles you can read the current applied filters using getComputedStyle and add more to the mix.

And a relevant article - this is more for animations and not yet supported by many browsers: Additive animations

And another relevant article on css-tricks: Houdini

6

I'm trying to create utility classes in vanilla CSS and this would be helpful but it looks like it can not be done this way.

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

I'm not sure why they didn't just create a more specific property like:

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

After some more work I came up with this solution:

/*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%;
}

I am using this.

/* Multiple filters */
backdrop-filter: url(filters.svg#filter) blur(4px) saturate(150%);

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like