I was recently doing some client work where I used both
<mask>s in SVG to hide and show content for animation. When I started this project, I thought I knew all of the reasons to use one over the other. But, as tends to happen, working closely with something reveals idiosyncrasies. In this post, we’ll go over some of these details so that you can get productive as soon as possible.
What is clipping and masking and why should we care about it?
Both clipping and masking obscure areas where elements in an SVG or HTML element can be visually applied. You use a bit of SVG designated as a
<mask> by wrapping the element and applying an id, like so:
See the Pen d2a9315e310901a3d43ba3bdf8413c65 by Sarah Drasner (@sdras) on CodePen.
Though no demo of these techniques will rival Yoksel‘s version, which is comprehensive not just to SVG but to CSS versions of clipping and masking as well:
See the Pen CSS and SVG Masks by yoksel (@yoksel) on CodePen.
These techniques are so useful because we can show and hide bits of content, which we can use for unique layouts, realism in animation, and performant alternatives to height transitions.
<clipPath> in SVG (or
clip-path in CSS) as a way to cut a shape out of another shape. There’s no concept of opacity, or alpha channel, to gray area here. Parts of the element with a clipping path applied are literally visible or not visible. Clipping just uses the geometry of the shape. Because of this, certain visual elements won’t be applied. This includes, but is not limited to: stroke and stroke styles, gradients, and fill colors.
You can still, however, animate these visual elements, change their attributes, and apply transforms to them, these will still be honored. Remember that when you animate them you need to target the elements inside the
<clipPath>. Another thing to keep in mind is that the pieces that are clipped away won’t accept pointer events, so events can only be captured on the parts that you can visually see.
Check out the Wall-e demo below. Do you see how the arms are being obscured as they reach out and then tuck back into the body? In order to realistically hide and show that arm, we will need to obscure it as it moves. In this case, we made a
clipPath out of the elbow curve and clipped pieces of the arm as it extended.
See the Pen Vue-controlled Wall-E by Sarah Drasner (@sdras) on CodePen.
It doesn’t end there, of course, we can apply this technique to more sophisticated effects, such as this amazing x-ray machine from Noel Delgado:
See the Pen X-ray me (SVG Experiment) by Noel Delgado (@noeldelgado) on CodePen.
Think about masking as a way to apply complex, detailed, and shapes with varying opacity over another element. This can lead to really beautiful visual effects and performant alternatives to other techniques. For instance, animating gradients can be really CPU-intensive. But in the graphic below, we’re animating the mask instead of the gradient to the same visual effect, and it’s a lot less heavy.
See the Pen Animating transparent mask by Sarah Drasner (@sdras) on CodePen.
Because SVG supports text and each piece is editable, we can also create interesting effects to show and hide pieces of data that are changing. Check out this demo from Craig Roblewsky:
See the Pen Quick Tip: Invert SVG text fill color with masks by Craig Roblewsky (@PointC) on CodePen.
Unlike clipping, masking does respect stroke and stroke effects, but keep in mind that in a mask, it will treat white as an area that will be shown and black as an area to be masked, with the greyscale exposing each along that scale.
This means, though, that you can use gifs with white and transparency to create masks that expose really cool effects:
See the Pen Gif masking in SVG by Sarah Drasner (@sdras) on CodePen.
I learned everything I needed to learn to make the above demo from Yoksel, who has a vast collection of pens with this technique, here’s one I particularly like with a bird and a gradient, and a subtle texture in the background.
See the Pen Rainbow bird by yoksel (@yoksel) on CodePen.
I love this topic. I can definitely see the confusion between “clipping” and “masking” – they feel like they are just synonyms! But as you clearly showed, they work differently and are coded differently.
Just in case another variation of an explanation helps, this is how I tackled it in Practical SVG:
Clipping might be slightly easier to understand, particularly if you’re comfortable with vector shapes. Just play with Clippy for a second and you’ll get a feel for clipping paths.
And here’s an image with a crack at explaining masking, and how it is based on an image:
Thanks for the interesting article. I gotta bite the bullet and do more CSS and JS, I am pretty weak on both and have mostly just been copying what I needed. Recently started doing a Flask site with Bootstrap so I am having to learn “modern” fancy CSS and JS.
I look forward to working with these techniques in the near future for my own site.