mask

Avatar of Mojtaba Seyedi
Mojtaba Seyedi on (Updated on )

Take your JavaScript to the next level at Frontend Masters.

The mask property is a shorthand to specify all mask-* properties. mask can hide part of the element is applied to and It accepts one or more comma-separated values, where each value corresponds to a mask layer.

.element {
  mask: url(mask.png) right bottom / 100px repeat-y;
}

mask is included in the CSS Masking Module 1 specification.

Syntax

mask: <mask-layer>#
where

<mask-layer> = <mask-reference> || <position> [ / <bg-size> ]? ||<repeat-style> || <geometry-box> || [ <geometry-box> | no-clip ] || <compositing-operator> || <masking-mode>
  • Initial value: see individual properties
  • Applies to: all elements. In SVG, it applies to container elements without the <defs> element, all graphics elements and the <use> element.
  • Inherited: no
  • Animation type: only the mask-position and mask-size properties are animatable.

Values

/* General examples */
mask: none;
mask: url(mask.svg);
mask: url(mask.png) luminance;
mask: url(mask.png) 100px 200px;
mask: url(mask.png) 100px 200px/50px 100px;
mask: url(mask.png) repeat-x;
mask: url(mask.png) 50% 50% / contain no-repeat border-box luminance;

/* Global values */
mask: inherit;
mask: initial;
mask: unset;

/* Multiple masks */
mask: url(mask.png) luminance center repeat-y exclude,
      linear-gradient(black, transparent);

The mask property accepts the following values, each of which is takes the value of a mask constituent property, including:

ValuePropertyWhat it doesDemo
<mask-reference>mask-imageSets the image that is used as an element’s mask layer.CodePen
<masking-mode>mask-modeIndicates whether the CSS mask layer image is treated as an alpha mask or a luminance mask.CodePen
<position>mask-positionSpecifies the initial position of a mask layer image relative to the mask position area.CodePen
<bg-size>mask-sizeSpecifies the size of a mask layer image.CodePen
<repeat-style>mask-repeatTells a mask if it should repeated or not and in which directions.CodePen
<geometry-box>mask-originSpecifies the mask position area of a mask layer image. In other words, it defines where the origin of the mask layer image is, whether it’s the edge of the border, padding or content box.CodePen
mask-clipDetermines the area which is affected by a mask. The painted content of an element must be restricted to this area.CodePen
<compositing-operator>mask-compositeAllows us to combine a mask layer image with the mask layers below it.CodePen

Not all values need to be declared in the shorthand

The mask shorthand property assigns explicit values and sets missing properties to their initial values. In the following example we use the mask property shorthand to specify just the values for the mask-image and mask-repeat properties:

.element {
  mask: url(mask.png) repeat-x;
}

That is equivalent to the following:

.element {
  mask-image: url(mask.png);
  mask-mode: match-source;     /* initial value */
  mask-position: center;       /* initial value */
  mask-size: auto;             /* initial value */
  mask-repeat: repeat-x;
  mask-origin: border-box;     /* initial value */
  mask-clip: border-box;       /* initial value */
  mask-composite: add;         /* initial value */
}

The order of the values does kinda matter

The values in the mask shorthand can be ordered however you like, with one exception being the mask-size property value. That must go after the mask-position property value and both values need to be separated by a forward slash (/).

mask: url(mask.png) 120px 30px;                /* mask-position */
mask: url(mask.png) 100px 200px / 50px 100px;  /* mask-position / mask-size */
mask: url(mask.png) contain no-repeat;         /* Invalid declaration */

mask resets mask-border to its initial value

You might not see mask-border in the examples we’ve seen so far, but it’s still doing something in the background because mask resets mask-border to its initial value. Remember, mask-border is a shorthand property as well, so here’s how that breaks down:

mask-border-mode: alpha
mask-border-outset: 0
mask-border-repeat: stretch
mask-border-slice: 0
mask-border-source: none
mask-border-width: auto

As such, the spec suggests using mask instead of the individual properties to override mask settings that pop up earlier in the cascade. That way, too, mask-border properties are properly reset to their initial values, allowing the styles declared later to work as expected.

Setting the <geometry-box> value with mask-clip and mask-origin

Both mask-clip and mask-origin take a <geometry-box> value. So there are a couple of things to keep in mind.

First, if there is one <geometry-box> value and the no-clip keyword, then:

  • mask-origin is the <geometry-box>
  • mask-clip is set to no-clip
mask: url(mask.png) content-box no-clip;
/**
mask-origin: content-box;
mask-clip: no-clip;
*/

If there is one <geometry-box> value but no no-clip keyword, then both mask-origin and mask-clip are set to the<geometry-box> value.

mask: url(mask.png) content-box;
/**
mask-origin: content-box;
mask-clip: content-box;
*/

How about two <geometry-box> values?

  • The first sets mask-origin
  • The second sets mask-clip
mask: url(mask.png) content-box border-box;
/**
mask-origin: content-box;
mask-clip: border-box;
*/

Example

The following example uses two mask layers on top of an image:

Browser support

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

Desktop

ChromeFirefoxIEEdgeSafari
98*53No95*TP*

Mobile / Tablet

Android ChromeAndroid FirefoxAndroidiOS Safari
94*9294*15*

More information

Tricks!