Search code examples
cssbackground-imagemix-blend-mode

Difference between <img> and background-image with mix-blend-mode


I'm attempting to create a duotone effect similar to the ones shown on this pen: https://codepen.io/meowwwls/pen/zoRjdK

My attempt is here and works exactly how I want it to for a plain img tag: https://codepen.io/sunnywz/pen/zPyYYR

$dark_blue: #080c29;
$white_blue: #dbe6ec;

.duotone {

display: inline-block;
position: relative;
vertical-align: top;
width: auto;

&:before,
&:after {
    content: "";
    opacity: 1;
    pointer-events: none;
    position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
    transition: 0.5s;
        -webkit-transition: 0.5s;
}

&:before {
    background: $dark_blue;
    mix-blend-mode: color;
    z-index: 1;
}

&:after {
    background: $white_blue;
    mix-blend-mode: color;
    z-index: 2;
}

img {
    filter: grayscale(1) contrast(1) brightness(1);
        -webkit-filter: grayscale(1) contrast(1) brightness(1);
    vertical-align: middle;
}

&:hover {
    &:before,
    &:after {
        opacity: 0;
        transition: 0.5s;
            -webkit-transition: 0.5s;
    }
    img {
        filter: none;
            -webkit-filter: none;
    }
}

}

.duotone-background {

background-size: cover;
display: inline-block;
filter: grayscale(1) contrast(1) brightness(1);
    -webkit-filter: grayscale(1) contrast(1) brightness(1);
height: 386px;
position: relative;
width: 640px;
vertical-align: top;

&:before,
&:after {
    content: "";
    opacity: 1;
    pointer-events: none;
    position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
    transition: 0.5s;
        -webkit-transition: 0.5s;
}

&:before {
    background: $dark_blue;
    mix-blend-mode: color;
    z-index: 1;
}

&:after {
    background: $white_blue;
    mix-blend-mode: color;
    z-index: 2;
}

&:hover {
    filter: none;
        -webkit-filter: none;
    &:before,
    &:after {
        opacity: 0;
        transition: 0.5s;
            -webkit-transition: 0.5s;
    }
}

}

But when I apply the same styles and pseudoelements to a div with a background image, it comes out a completely different effect as you can see by the second image.

I've attempted to use the $dark_blue color on the div with a background-blend-mode and that didn't seem to work at all.

How can I achieve the same effect on the background image?


Solution

  • One thing you could do is just replace the <img /> with a <div style="background-image: url(...)"></div> and adjust the styles accordingly (replace img with div essentially - also giving the div dimensions width: 100%; height: 100%; ). That way its "layered" the same.

    so your markup would be:

    <div class="duotone-background" >
      <div style="background-image: url('http://dlvec.btmcdev.com/wp-content/uploads/2017/11/Screen-Shot-2017-11-21-at-10.07.07-AM-1024x617.jpg')"></div>
    </div> 
    

    styles:

    .duotone-background {
        display: inline-block;
        height: 386px;
        position: relative;
        width: 640px;
      vertical-align: top;
    
        &:before,
        &:after {
            content: "";
            opacity: 1;
            pointer-events: none;
            position: absolute;
                top: 0;
                right: 0;
                bottom: 0;
                left: 0;
            transition: 0.5s;
                -webkit-transition: 0.5s;
        }
    
        &:before {
            background: $dark_blue;
            mix-blend-mode: color;
            z-index: 1;
        }
    
        &:after {
            background: $white_blue;
            mix-blend-mode: color;
            z-index: 2;
        }
    
        &:hover {
            filter: none;
                -webkit-filter: none;
            &:before,
            &:after {
                opacity: 0;
                transition: 0.5s;
                    -webkit-transition: 0.5s;
            }
    
        div {
          filter: none;
                -webkit-filter: none;
        }
        }
    
      div {
        width: 100%;
        height: 100%;
        background-size: cover;
        filter: grayscale(1) contrast(1) brightness(1);
            -webkit-filter: grayscale(1) contrast(1) brightness(1);
      }
    }
    

    See this updated CodePen