Home

Using mask as clip-path

18 February 2022

When I first learned that the path() function is supported in the clip-path attribute, I was quite excited because it allows clipping with complex shapes other than ellipse or polygons.

clip-path: path('M 5 5 h 100 v 100 Z');

But soon I found out it was not responsive. The size of the shape does not change with its container. Numbers are in px and there's no option to use relative values. Since then I've been waiting for browsers to provide a way to set its viewBox value like in SVG.

Until recently as I was trying to distinguish mask and clip-path, I realized the responsive path() function in clip-path can be easily achieved with mask and it's more flexible.

Mask

The main difference between mask and clip-path is that mask uses images as input.

mask: url('shape.svg');

So SVG files can be used as masks, and we can put path elements inside SVG with viewBox properly defined.

<!-- shape.svg -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="8 5 135 135">
  <path d="
    M15 45
    A30 30 0 0 1 75 45
    A30 30 0 0 1 135 45
    Q135 90 75 130
    Q15 90 15 45"
  />
</svg>

Now it's responsive.

Why didn't I figure it out before?

Using mask is not straightforward as clip-path because it requires a separate file by default. However, data URIs makes it possible to write SVG directly inside CSS file. It's still sort of hard to read and write though.

mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='8 5 135 135'%3E%3Cpath d='M15 45 A30 30 0 0 1 75 45 A30 30 0 0 1 135 45 Q135 90 75 130 Q15 90 15 45'/%3E%3C/svg%3E");

But what if I can write them like this:

/* css-doodle */

mask: @svg(
  viewBox: 8 5 135 135;
  path {
    d: M 15 45
       A 30 30 0 0 1 75 45
       A 30 30 0 0 1 135 45
       Q 135 90 75 130
       Q 15 90 15 45
  }
)

It looks pretty close to using path() function in clip-path.

Although the idea of replacing clip-path with mask for responsive clipping seems so obvious, the above new syntax from css-doodle finally helped me to come up with this idea today, after one year!

I no longer stick to clip-path.

Syntax matters

The (programming) languages we're using do influence how we think. They provide not only the vocabularies to express something, but also different perspectives.