CSS Masks in WebKit

written by Jedidiah Broadbent

Note: To follow along at home and to play with the demos you will need to be using a WebKit based browser such as Safari, Chrome or Konquerer as CSS masks are not part of the specification yet and are only implemented in WebKit. For the moment unless you are building only for a controlled environment (iPhone/iPad/tuneKit etc.) where you know it will work for 100% of users, this will probably only be useful for personal projects.

Introduction

This article is an introduction into using CSS Masks as implemented in Webkit, if you just want to skip the waffle and jump straight into the demos they are listed on the right along with some helpful resources for reading about CSS Masks.

Licenses

The article and demos are licensed under Creative Commons, and the photos from some of the demos are taken from Flickr also under Creative Commons, please respect the individual attribution if you redistribute this article in your school/university. The attribution for the photos is at the bottom of each page.

Please send any questions, corrections or comments to hello@jedidiah.eu.

Overview

Lets start by getting everyone up to speed, what is a mask? If you have ever painted a window frame or are a dab hand at photoshop you have probably got an idea of the kind of mask we are talking about, if you thought Phantom of the Opera, sorry close but no biscuit.

Masks are a way of only showing (‘masking off’) a small area of a larger object without destroying the areas that are removed. Think of mount board round a photo in a picture frame, there is more of the photo behind the board you just can’t see it. You can move the photo behind the mount board or you could make the mount larger or smaller to reveal or hide more of the photo. If you wanted to get creative you could even cut the mount board into some fancy shapes.

So how does this apply in CSS?

Syntax

Masks in CSS are mostly treated the same way as backgrounds, they can be made with images, SVG files (although currently some limitations apply, which we will go into later) and generated gradients. In the same way you have multiple backgrounds you can have multiple masks, and like background all of mask’s properties can be animated with CSS or Javascript.

The properties that Apple list on their developer documentation are:

-webkit-mask
-webkit-mask-attachment
-webkit-mask-box-image
-webkit-mask-clip
-webkit-mask-composite
-webkit-mask-image
-webkit-mask-origin
-webkit-mask-position
-webkit-mask-position-x
-webkit-mask-position-y
-webkit-mask-repeat
-webkit-mask-size

You should recognise all of them from the properties on background. The shorthand alternative to background:; is -webkit-mask:;

Simple Example

First we include our favourite periwinkle photo…

<img class="cutout" src="images/periwinkle.jpg" alt="">

…and we find a suitable image to use as a mask and add the following to the stylesheet

.cutout{
    -webkit-mask:url(images/heartmask2.png) no-repeat center center;
}

You would end up with something like this:

I know some of you are thinking “I could do that in photoshop and save it as a png with transparency, why would I want to do it like this?”. One obvious example is file size, our periwinkle photo is 29KB and our heart mask is 8KB giving us a grand total of 37KB, for comparison the same image saved from photoshop is 139KB.

Using masks you also gain a lot of flexibility, you could swap out the image dynamically keeping the same mask, or use the same mask for multiple images without having to save out new files. Masks can also be moved or scaled, have a look at this demo (Hidden World) or try hovering over the heart below.

<img class="cutout pulse" src="images/periwinkle.jpg" alt="">


     .cutout{
         -webkit-mask: url(images/heartmask2.png) no-repeat center center;
     }

     .cutout.pulse:hover{
         -webkit-animation-name: pulsed;
         -webkit-animation-duration: 1s;
         -webkit-animation-timing-function: ease-in-out;
         -webkit-animation-iteration-count: infinite;
         -webkit-animation-direction:alternate;
         -webkit-mask-size: auto 100%;
     }
     @-webkit-keyframes pulsed {
         0% { -webkit-mask-size: auto 100%; }
         100% { -webkit-mask-size: auto 90%; }
     }

Creative Commons License Introduction to CSS Masks in Webkit (including the accompanying demos) by Jedidiah Broadbent is licensed under a Creative Commons Attribution-Non-Commercial-Share Alike 2.0 License.