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.
