Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

combining background-blend-mode & grayscale in images

I know the background-blend-mode is a new css feature but I was wondering is it in any way able to be combined with filter techniques in css.

Basically what I am trying to achieve is for an image to change from full colour to being desaturated and blended to a coloured background on hover (blend mode multiply).

Below is an example of what I've tried, as you can see the red image works fine as it is a dark colour but for orange and yellow the colours of the original image show through the yellow as they are darker, so the image needs to be desaturated. The final example #yellow2 is how I've tried to achieve the desaturation but it then causes the image to ignore the blend mode.

http://jsfiddle.net/cstr44/dzwH4/2/

<div id="red"></div>

<div id="orange"></div>

<div id="yellow"></div>

<div id="yellow2"></div>

    #red{
width:250px;
height:200px;
background:red url(http://www.mucky-pups.co/wp-content/uploads/2013/05/9.jpg);
background-size:250px 200px;}

#red:hover{
background-blend-mode: multiply; }

#orange{
width:250px;
height:200px;
background:orange url(http://0.tqn.com/d/friendship/1/S/R/-/-/-/special-dog-breeds.jpg); background-size:250px 200px;}

#orange:hover{
background-blend-mode: multiply;}

#yellow{ 
width:250px;
height:200px;
background:yellow url(http://stylonica.com/wp-content/uploads/2014/03/Puppy-3-dogs-1993798-1024-76811.jpg); background-size:250px 200px;}

#yellow:hover{ 
background-blend-mode: multiply;}

#yellow2{ 
width:250px;
height:200px;
background:yellow url(http://stylonica.com/wp-content/uploads/2014/03/Puppy-3-dogs-1993798-1024-76811.jpg); background-size:250px 200px;
}

#yellow2:hover{ 
background-blend-mode: multiply;
filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#grayscale");
filter: gray;
-webkit-filter: grayscale(100%);}

Is there any other way that this might be possible?(other than creating a desaturated version of every image)

like image 885
cstr44 Avatar asked Feb 01 '26 13:02

cstr44


1 Answers

I think I've achieved what you're after. The solution only works in Chrome for now.

Visit chrome://flags/ and "Enable experimental Web Platform features" to see effect.

The combination of applying a filter and a blend mode to the same element was failing. In fact, I attempted to continue the use of the grayscale filter on the element with the image and then I overlaid a new element and tried mix-blend-mode. That failed also.

Ultimately, I created two new elements (layers) positioned above your image. Then I used mix-blend-mode to achieve the effect. The first element (layer just above image) used mix-blend-mode: saturation with a background color of black (or white) to convert your image to greyscale. The topmost element had the yellow color and mix-blend-mode: multiply.

I used the pseudo elements :before and :after so that you could leave your markup unchanged.

http://jsfiddle.net/dzwH4/8/

<div id="red"></div>

<div id="orange"></div>

<div id="yellow"></div>

<div id="yellow2"></div>

#red{
width:250px;
height:200px;
background:red url(http://www.mucky-pups.co/wp-content/uploads/2013/05/9.jpg);
background-size:250px 200px;}

#red:hover{
background-blend-mode: multiply; }

#orange{
width:250px;
height:200px;
background:orange url(http://0.tqn.com/d/friendship/1/S/R/-/-/-/special-dog-breeds.jpg); background-size:250px 200px;}

#orange:hover{
background-blend-mode: multiply;}

#yellow{ 
width:250px;
height:200px;
background:yellow url(http://stylonica.com/wp-content/uploads/2014/03/Puppy-3-dogs-1993798-1024-76811.jpg); background-size:250px 200px;}

#yellow:hover{ 
background-blend-mode: multiply;}

#yellow2{ 
    width:250px;
    height:200px;
    background:yellow url(http://stylonica.com/wp-content/uploads/2014/03/Puppy-3-dogs-1993798-1024-76811.jpg); background-size:250px 200px;
    position: relative;
}

#yellow2:after, #yellow2:before {
    content: ' ';
    display: none;
    height: 100%;
    left: 0;
    position: absolute;
    top: 0;
    width: 100%;
}
#yellow2:before {
    background-color: black;
    mix-blend-mode: saturation;
}
#yellow2:after {
    background-color: yellow;
    mix-blend-mode: multiply;
}

#yellow2:hover:before, #yellow2:hover:after {
    display: block;
}

If you are looking for a cross-browser solution, you might take the same approach using feBlend for SVG (FF, IE10, etc.) and dxFilters for IE<=9.

UPDATE:

Here's an SVG solution that I tested on Chrome, FF, Opera, IE10, IE11, Safari 7 OSX.

http://jsfiddle.net/5pmmet6b/4/

<div id="puppy">
    <svg>
        <defs>
            <filter id="colorize_yellow" color-interpolation-filters="sRGB">
                <feFlood flood-color="yellow" result="A"/>
                <feColorMatrix type="saturate" in="SourceGraphic" values="0" result="B"/>
                <feBlend mode="multiply" in2="B" in="A"/>
            </filter>
        </defs>
        <image id="yellow" filter="url(#colorize_yellow)" x="0" y="0" width="100%" height="100%" xlink:href="http://stylonica.com/wp-content/uploads/2014/03/Puppy-3-dogs-1993798-1024-76811.jpg"/>
    </svg>
</div>

#puppy {
    background: url('http://stylonica.com/wp-content/uploads/2014/03/Puppy-3-dogs-1993798-1024-76811.jpg');
    background-size: 249px 187px;
    position: relative;
}
#puppy svg {
    left: 0;
    overflow: hidden;
    position: absolute;
    top: 0;
}
#puppy, #puppy svg {
    height: 187px;
    width: 249px;
}
#yellow {
    opacity: 0;
}
#yellow:hover {
    opacity: 1;
}

Older Internet Explorer Method:

Works in IE 6-9:

<!DOCTYPE html>

<html>

<head>
    <title>Light Filter Sample</title>
    <style type="text/css">
        div, img {
            height: 200px;
            width: 250px;
        }
        #image {
            position: relative;
        }
        #grayscale {
            -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(grayscale=1)";
            filter: progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);
        }
        #yellow {
            display: none;
            -ms-filter: "progid:DXImageTransform.Microsoft.Light()";
            filter: progid:DXImageTransform.Microsoft.Light();
            left: 0;
            position: absolute;
            top: 0;
        }
        /* NOTE: you'll need to use script for hovering support on IE6 */
        #image:hover #yellow {
            display: block;
        }
    </style>
    <script type="text/javascript">
        window.onload = function () {
            document.getElementById('yellow').filters.item("DXImageTransform.Microsoft.Light").addAmbient(255, 255, 0, 100);
        }
    </script>
</head>

<body>
    <div id="image">
        <img src="http://stylonica.com/wp-content/uploads/2014/03/Puppy-3-dogs-1993798-1024-76811.jpg" alt="">
        <div id="yellow">
            <div id="grayscale">
                <img src="http://stylonica.com/wp-content/uploads/2014/03/Puppy-3-dogs-1993798-1024-76811.jpg" alt="">
            </div>
        </div>
    </div>
</body>

</html>
like image 74
ifugu Avatar answered Feb 04 '26 06:02

ifugu



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!