Css masking with blend-modes

, 27/04/2016

I’ve been very impressed by the site of Nurture Digital created by Bryan James so I wanted to recreate the masking technic he used for the home page. I searched the web, but could not find answers about masking technic using blend-modes. There were some tricks using clip-path property or fixed background position, but this couldn’t allow me to reach my goal.

In this demo I will try to recreate this masking technic, and next I will add the following mouse’s effect like it’s made on nurturedigital. This css masking technic uses the blend-modes property so you can reproduce it as well inside photoshop . It’s based on two differents blend-modes : multiply and screen. ( Note Css blend-modes is not supported by IE )

Now let see how it’s done !

The html markups :

<div class="wrapper full-size">
    <!-- This div handle the background color -->
    <div class="mask-bg-color full-size">
    </div>
    <!-- This div  wrap all other elements with blend-mode multiply apply -->
    <div class="blend-multiply full-size">    
        <!-- This div handle the background element (could be an image, a video or in that case a gif) -->
        <div class="animated-bg full-size">
        </div>
        <!-- This div wrap the masked element with blend-mode screen apply 
             and background-color set as #ffffff -->
        <div class="blend-screen element-mask full-size">
            <!-- This span display the masked element-->
            <span id="circle" class="circle-follow">
            </span>
        </div>
    </div>
</div>

As you can see two modes are applied : multiply for parent’s wrapper and screen for the child element’s mask. This one must have a white background color and his child – here the circle – must have a black background color. This is important because if it’s not set correctly the mask will not work.

 

The css properties :

body, html {
    position: relative;
    overflow : hidden;
    height: 100%;
    width : 100%;
    margin: 0;
}

h1, p, a {
    font-family: 'Roboto', Arial, Helvetica, sans-serif;
    color:#fff;
    margin: 0;
}
h1 {
    text-transform: uppercase;
    font-size: 3em;
}
p {
    font-size : 1em;
}

.full-size {
    height : 100%;
    width : 100%;
    position: absolute;
    top : 0;
    left : 0;
}
.blend-multiply {
    mix-blend-mode : multiply;
}
.blend-screen {
    mix-blend-mode : screen;
}

.mask-bg-color {
    background-color: #50c7f8;
}
.animated-bg {
    background-image: url('http://hmongouachon.com/assets/gif/timelapse.gif');
    background-position:center;
    -moz-background-size:cover;
    -o-background-size:cover;
    -webkit-background-size:cover;
    background-size:cover;
}
.element-mask {
    background-color: #fff;
}

.circle-follow {
    position :absolute;
    overflow : hidden;
    background-color: #000000;
    width :320px;
    height: 320px;
    top:calc( 50% - 160px);
    left:calc( 50% - 160px);
    -webkit-border-radius: 160px;
    border-radius: 160px;
    -webkit-transition: opacity 0.3s cubic-bezier(0.52, 0.01, 0.16, 1);
    transition: opacity 0.3s cubic-bezier(0.52, 0.01, 0.16, 1);
    /*opacity : 0;*/
}
.circle-follow::before  {
    content : ' ';
    height : 100%;
    width : 100%;
    position: absolute;
    top : 0;
    left : 0;
}

/* hack to detect ie11 and above - blend mode not supported */
_:-ms-fullscreen, :root .letter-mask {background-color: transparent; }
_:-ms-fullscreen, :root .animated-bg {opacity: 0.2;}
_:-ms-fullscreen, :root .circle-follow {background-color:#ffffff; opacity: 0.2; }

 

And your circle is now displaying the gif background as a mask !

circle-mask-blend-mode

 

Now let’s add some interactivity with a little bit of jQuery. We want our circle to appear and follow the mouse movements with momentum, and when the mouse stops moving, the circle will fades out.

First we have to hide the div called « circle-follow » by setting opacity to 0 and assigning a duration to the transition property . Next we add a new class named « moving » to the circle, because we will add this class name with jQuery when the mouse start moving. If the mouse stops moving, we remove this class with jQuery :

.circle-follow {
    /* other properties */
    -webkit-transition: opacity 0.3s cubic-bezier(0.52, 0.01, 0.16, 1);
    transition: opacity 0.3s cubic-bezier(0.52, 0.01, 0.16, 1);
    opacity : 0;
}
.circle-follow.moving {
    opacity : 1;
}

Now it’s time to add some magic with jQuery :

The javascript rules  :

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script>
    jQuery(document).ready(function($) {

        // set the variables
        var timer;
        var mouseX = 0, mouseY = 0;
        var xp = 0, yp =0;
        var circle = $("#circle");

        function mouseStopped(){
            // if mouse stop moving remove class moving
            // it will hide the circle with opacity transition
            circle.removeClass('moving');
        }

       $(document).mousemove(function(e){
           // if mouse start moving add class moving
           // it will show the circle with opacity transition
           circle.addClass('moving');
           // get the mouse position minus 160px to center the circle
           mouseX = e.pageX - 160;
           mouseY = e.pageY - 160;
           // if mouse stop moving clear timer and call mouseStopped function
           clearTimeout(timer);
           timer=setTimeout(mouseStopped,3000);
       });

       // set the momentum with setInterval function
       var loop = setInterval(function(){
           // change 12 to alter damping higher is slower
           xp += ((mouseX - xp)/6);
           yp += ((mouseY - yp)/6);
           circle.css({left: xp +'px', top: yp +'px'});  //
       }, 30);

    });
</script>

That’s it ! Hope you enjoy this tutorial !

View this demo on codepen