CSS Masks

CSS masks control which parts of an element are visible by using an image, gradient, or other mask source. A mask can fully reveal content, completely hide it, or create partially transparent areas between the two.

Unlike clipping, which creates a defined visible region, masking can use varying transparency to produce soft edges, fades, patterns, and more detailed visibility effects.

How Masks Work

A mask provides transparency information that determines how much of an element is visible. Fully opaque areas of an alpha mask reveal the element, transparent areas hide it, and partially transparent areas reveal it partially.

.box {
  mask-image: linear-gradient(to right, #000, transparent);
}

This mask begins opaque and gradually becomes transparent, causing the element to fade from visible to hidden.

The mask affects the rendering of the element and its contents without changing the element's normal layout dimensions.

mask-image

The mask-image property specifies the image or generated image used as the mask.

.box {
  mask-image: linear-gradient(to right, #000, transparent);
}

CSS gradients are especially useful as mask images because they can create masks without requiring separate image files.

An external image can also be used as a mask source.

.box {
  mask-image: url("mask.png");
}

The initial value is none, which means no mask image is applied.

Gradient Masks

Linear, radial, and conic gradients can be used as mask images. Their transparency controls which portions of the element remain visible.

.fade {
  mask-image: linear-gradient(to right, #000, transparent);
}

A radial gradient can reveal the center of an element while gradually hiding its outer edges.

.spotlight {
  mask-image: radial-gradient(circle, #000 30%, transparent 70%);
}

Hard color stops can also create sharply defined visible and hidden areas.

.half {
  mask-image: linear-gradient(
    to right,
    #000 0%,
    #000 50%,
    transparent 50%,
    transparent 100%
  );
}

mask-size

The mask-size property controls the size of the mask image.

.box {
  mask-image: radial-gradient(circle, #000 50%, transparent 51%);
  mask-size: 100px 100px;
}

Values can use lengths, percentages, or keywords such as cover and contain.

.box {
  mask-size: cover;
}

When a mask repeats, its size also determines the size of each repeated mask tile.

mask-position

The mask-position property controls the starting position of a mask image within its positioning area.

.box {
  mask-position: center;
}

Keywords, percentages, and lengths can be used to position the mask.

.box {
  mask-position: 75% 50%;
}

This can be useful when a mask should reveal a particular portion of an element.

mask-repeat

The mask-repeat property controls whether and how a mask image repeats.

.box {
  mask-repeat: no-repeat;
}

Common values include repeat, repeat-x, repeat-y, space, round, and no-repeat.

A small radial gradient can be repeated to create a patterned mask.

.box {
  mask-image: radial-gradient(circle, #000 50%, transparent 52%);
  mask-size: 40px 40px;
  mask-repeat: repeat;
}

mask-origin and mask-clip

The mask-origin property specifies the box used to position a mask layer, while mask-clip controls the area affected by the mask.

.box {
  mask-origin: content-box;
  mask-clip: content-box;
}

These properties can use box values such as border-box, padding-box, and content-box.

They are useful when an element has borders or padding and the mask needs to align with a particular part of the CSS box.

mask-mode

The mask-mode property controls whether a mask layer uses alpha information, luminance information, or the mode associated with the mask source.

.box {
  mask-mode: alpha;
}

With an alpha mask, transparency determines the mask effect. With a luminance mask, the luminance of the mask colors also contributes to how much of the element is revealed.

The match-source value allows the mask source to determine the appropriate masking mode.

Multiple Masks

Like CSS backgrounds, masks can contain multiple comma-separated layers.

.box {
  mask-image:
    radial-gradient(circle at left, #000 60%, transparent 61%),
    linear-gradient(to right, #000, transparent);
}

Each mask layer can have its own size, position, repetition, and other mask properties.

Multiple layers allow more complex masking effects to be built from simpler shapes and gradients.

mask Shorthand

The mask shorthand can combine several mask layer properties into a single declaration.

.box {
  mask: radial-gradient(circle, #000 50%, transparent 51%)
        center / 150px 150px no-repeat;
}

This declaration defines the mask image, position, size, and repetition behavior.

Individual mask properties can be easier to understand while learning, while the shorthand can make finished CSS more compact.

Masks vs clip-path

CSS masks and clip-path both control which portions of an element are visible, but they do so differently.

Feature Mask Clip Path
Visible boundary Can contain gradual transparency Primarily defines a clipping boundary
Soft fades Yes No
Basic geometric shapes Possible with mask images or gradients Directly supported with basic shapes
Image-based visibility Yes Uses clipping paths rather than image transparency
Multiple layers Yes Not as multiple clip-path layers

Use clip-path when a defined clipping boundary is appropriate. Masks are useful when the effect requires fades, partial transparency, repeating patterns, or detailed image-based visibility.

Common Mask Properties

Property Purpose
mask-image Specifies the mask image or gradient.
mask-size Controls the size of the mask image.
mask-position Positions the mask image.
mask-repeat Controls mask image repetition.
mask-origin Defines the positioning area for the mask.
mask-clip Defines the area affected by the mask.
mask-mode Controls how mask values are interpreted.
mask Shorthand for several mask properties.

CSS Mask Example

The following example applies four gradient masks to identical colored boxes. Each mask reveals the element in a different way.

.fade {
  mask-image: linear-gradient(to right, #000, transparent);
}
.circle {
  mask-image: radial-gradient(circle, #000 45%, transparent 46%);
}
.soft-circle {
  mask-image: radial-gradient(circle, #000 25%, transparent 70%);
}
.pattern {
  mask-image: radial-gradient(circle, #000 45%, transparent 50%);
  mask-size: 30px 30px;
}

Open the example in the editor and change the gradient directions, percentages, and mask sizes. Try reversing #000 and transparent to reverse which areas are revealed and hidden.

Play in Editor