问题
I'm trying to treat an image the same way it is in a photoshop file - desaturating the image to grayscale, and then applying a color overlay with a multiply blend mode. To this end, I am styling a CSS background image with...
.someclass
{
/* grayscale */
-webkit-filter: grayscale(1);
filter: gray;
filter: grayscale(1);
filter: url(desaturate.svg#greyscale);
/* multiply */
background-color: rgba(190, 50, 50, 0.65);
background-blend-mode: multiply;
}
The problem with this is that the grayscale filter ends up desaturating red color for the blend mode. In other words, the multiply is occurring first and then the grayscale. How do I switch it so that the grayscale is applied first and then the blend mode is applied second?
I have created a fiddle (http://jsfiddle.net/g54LcoL1/1/) for the code and a screenshot (made in Photoshop) of what I would expect the the fiddle result to look like. The bottom most image, div.grayscale.multiply
, should be colored red.
回答1:
You can not do it with filter, but you can do it staying with blend mode for everything
the grayscale equivalent in blend is luminosity, with the image as source and a solid white as backdrop
So the background images, from bottom to top, are:
- white (as background-color)
- your image
- solid red (that must be specified as a gradient for now)
and the blend modes are luminosity and multiply
.test {
width: 400px;
height: 400px;
background-image: linear-gradient(0deg, red, red), url("http://cuteoverload.files.wordpress.com/kitteh_puddle-1312.jpg");
background-color: white;
background-blend-mode: multiply, luminosity;
background-size: cover;
}
<div class="test"></div>
回答2:
The blend mode is applied to the background layers, and then the filter is applied to the whole element, so they are sort of dealing with two different things: by the time that the background is calculated (including the red-ish appearance), the whole element is converted to grayscale with the filter.
There is a proposed filter() function for image references, so in theory, you should be able to apply a filter to any image as it is loaded. I think this is the idea:
.someclass {
background-image: filter(cat.jpg, grayscale(100%));
background-color: red;
background-blend-mode: multiply;
}
Sadly, I don't think this is implemented anywhere yet, it's just in the draft version of the Filters spec.
In general, the order of operations in terms of these types of "post-processing" CSS effects is defined in the same order as for SVG: filtering is done first, then clipping, then masking, then blending.
(See the Blending & Compositing Spec.) So, there's nothing you can do in terms of changing that, I'm afraid.
回答3:
As Joel mentioned in his comment under the accepted answer, it's possible to do this using mix-blend-mode
.
In my example I'm going to use an actual image instead of a background image. If it has to be a background image then you can still use the same technique. Just replace the image with an empty div that has background image styling.
Also I'm going to use the "screen" blend mode instead of "multiply" because it demonstrates the color removal more clearly.
With color removal:
.image-wrapper {
background: red;
display: inline-block;
}
.image-wrapper img {
mix-blend-mode: screen;
filter: grayscale(100%);
}
<div class="image-wrapper">
<img src="https://static.decalgirl.com/assets/designs/large/clrkit.jpg" alt="Colorful cats"/>
</div>
Without color removal:
.image-wrapper {
background: red;
display: inline-block;
}
.image-wrapper img {
mix-blend-mode: screen;
}
<div class="image-wrapper">
<img src="https://static.decalgirl.com/assets/designs/large/clrkit.jpg" alt="Colorful cats"/>
</div>
More information can be found here:
https://css-tricks.com/almanac/properties/m/mix-blend-mode/
来源:https://stackoverflow.com/questions/25836628/css-grayscale-filter-and-background-blend-mode-at-same-time