CSS Clipping and Masking — Show and Hide Parts of Images and Elements with Code

If you’ve done any work with a graphics editor, you likely know what clipping and masking are. Both hide parts of elements visually. Clipping defines which part of an element to show and which to hide, while masking combines two elements to determine how much of each pixel should be transparent.

Both are coming to css, In fact they’re already here for more browsers than not. Safari, Chrome, Opera, iOS Safari, and Blackberry browser should have support using the -webkit prefix. Internet Explorer, Firefox, and Opera Mini don’t. In practice I couldn’t get Safari to respond, though everything worked as expected in Webkit Nightly suggesting they will work in Safari soon.

Similar to last week, there’s a lot to cover so I’ll walk you through the css masking spec today and present some examples and code on Thursday.

Illustration of a clipping path
Clipping region showing how top, right, bottom, and left distances are measured

CSS Clipping Paths

Clipping constrains the region in which an element is rendered. Anything inside the clipping path is drawn and anything outside the clipping path isn’t. Clipping in css isn’t anything new. It was defined in css 2.1, but the only shape you could use to clip an element in that definition was a rectangle.

1
2
p {clip: top, right, bottom, left;}
p {clip: 10px, 100px, 75px, 5px;}

Each of the above values is measured from the top left corner so the second line of css above creates a clipping area from 5px to 100px from the left edge and 10px to 75px from the top edge.

CSS3 is extending the shapes so we’re not limited to rectangular clipping paths. The clip property above is being deprecated in favor of the new clip-path, which enables you to define different shapes or to use a scalable vector graphic as the source of the path.

1
clip-path: <basic-shape> | <clip-source> | none;

The path can be applied to any and all html elements including SVG elements and SVG containers. In my previous post on css shapes I listed the basic shapes you could create. Here they are again.

1
2
3
4
rectangle(<top>, <left>, <width>, <height>, <rx>, <ry>);
circle(<cx>, <cy>, <r>);
ellipse(<cx>, <cy>, <rx>, <ry>);
polygon(<x1> <y1>, <x2> <y2>, ..., <xn> <yn>);

The value of clip-source adds more options

1
<clip-source> = <url> | child | <child-selector>;

child and child-selector point to a descendent element. The former indicates that the last direct child should be used for the clip-path, while the latter gives you more control in specifying which child to use. url points to an external SVG, which defines a clipPath that can use any svg shape.

Here’s an example using a clipPath inside an SVG from an HTML Rocks article on clipping and masking I recommend reading the article as it offers more good examples and explanation of both clipping and masking.

1
2
3
4
5
6
7
< svg>
  <defs>
    <clipPath id="clipping">
      <circle cx="284" cy="213" r="213" />
    </clipPath>
  </defs>
< /svg&gt
Illustration of the effect of  a luminance mask
An object, a luminance mask, and the result of combining them

CSS Masking

Masks take things a bit further. Instead of defining absolute paths where inside is visible and outside isn’t visible, masks filter what does and doesn’t show.

There are 2 types of masks that can be used.

  • luminance masks — Where the mask is black nothing in the element shows. Where the mask is white, everything in the element shows. For anything in between a portion of the element shows. The lighter the mask, the more of the element shows through.

  • alpha masks — Similar to luminance masks, except only the alpha channel of the mask is used. It may seem counterintuitive, but the more opaque the alpha mask, the more of the element shows through.

Layered Masks

Layered masks are what you’ll first think of when you think of masks. There are a number of properties for working with them that can later be combined in a single shortcut.

1
2
mask-image: <mask-reference>;
mask-reference = <mask-image># | <mask-source>;

The mask-reference can either be a mask-image or a mask source. I know that sounds a bit circular. The mask-image (in the mask-reference) can be the direct path to an image or something like a css gradient.

1
2
div {mask-image: url(mask.png);}
div {mask-image: linear-gradient(black 0%, transparent 100%);}

A mask-source is similar to clip-source that we saw above.

1
<mask-source> = <url> | child | <child-selector>;

The url would be a path to an external mask, like we saw above and child and child-selector also work the same way as they did for clip-path.

You can define the type of mask (luminance or alpha) using the mask-type or mask-source-type properties. The former is the more general property, which can be overwritten for specific masks by the latter.

1
2
mask-type: alpha | luminance;
mask-source-type: alpha | luminance | auto;

Masks can be positioned, and sized through the following 2 properties that are obviously named.

  • mask-position
  • mask-size

Both take the typical values of measurement (px, em, %). mask-position can also take keywords like right, bottom, center, etc.

Two more related properties are mask-origin and mask-clip. The former specifies the mask positioning area and the latter determines the mask painting area. They have similar possible values.

1
2
mask-origin: padding-box | border-box | content-box;
mask-clip: border-box | padding-box | content-box | no-clip;

In each case the first value is the default.

One last property to mention is mask-repeat, which specifies how mask images should be tiled after they’ve been sized and positioned.

1
mask-repeat: repeat-x | repeat-y | repeat | space | round | no-repeat;

The values are the same as those for background repeat. I’ll refer to my post on css-backgrounds for details on their definitions. In fact much of the above properties are similar to css background properties. If you want to understand how masking works, reading up on css backgrounds is probably a good idea.

Everything above can also be combined into a single mask shortcut property.

1
mask: <mask-layer>#;

where

1
<mask-layer> = <mask-reference><source-type>? || <position> [ / <bg-size> ]? || <repeat-style> || <box> || [ <box> | no-clip ];

Box-Image Masks

The divisions of a box image mask
The divisions of a box image mask

The other type of mask is the box-image mask. If you’re familiar with border-images, the following should be familiar.

The idea with box-image masks, is that the mask can be split into 9 pieces (4 corners, 4 edges, and a center). Each piece can be sliced, scaled, and stretched. The properties are so similar to the border-image properties that I’ll just refer you to my post on css border images for details on their values and how to work with each.

  • mask-box-image-source
  • mask-box-image-slice
  • mask-box-image-width
  • mask-box-image-outset
  • mask-box-image-repeat

Naturally there’s a shortcut to use all of the above.

1
mask-box-image: <‘mask-box-image-source’> || <‘mask-box-image-slice’> [ / <‘mask-box-image-width’> | / <‘mask-box-image-width’>? / <‘mask-box-image-outset’> ]? || <‘mask-box-image-repeat’>;

Summary

CSS clipping and masking offer some interesting effects that previously required a graphics editor to pull off. Browser support while better than expected, is not quite there yet. However, as most of these effects probably aren’t critical to functionality, you may want to consider using clipping and/or masking now.

I’d encourage you to read or reread information about css backgrounds and borders, since much about clipping and masking is similar. Understanding the former will help with understanding the latter.

On Thursday I’ll provide some examples of clipping and masking along with the code for how I achieved them. Again I hope you don’t mind the wait. It’ll give you a few days to experiment on your own if you’d like.

Download a free sample from my book, Design Fundamentals.

0 comments

Leave a Reply

Your email address will not be published.

css.php