Understanding CSS Masking Fundamentals
CSS masking enables you to reveal or hide parts of an element selectively by applying one or more mask images to it. These mask images can be gradients, images, or SVG sources. Unlike CSS clipping, which either fully shows or hides areas of an element based on the shape of a single path, masking allows for nuanced transparency and blending effects based on the alpha transparency and, optionally, luminance of the mask images (MDN Web Docs - Introduction to CSS Masking).
With alpha masks, the color of the mask is irrelevant--only the opacity matters. Wherever the mask is fully opaque, the element will be fully visible. At every pixel where the mask is fully transparent, the element will be fully hidden. Areas masked by partially opaque sections will display with matching opacity.
Luminance masks take brightness into account when determining visibility. Brighter, more opaque colors result in more opaque element regions, while darker, more transparent colors produce lower opacity. The brightness calculation uses the formula: ((0.2125 × R) + (0.7154 × G) + (0.0721 × B)) × A, where R, G, and B are color values and A is alpha.
Mastering these fundamental mask types opens up creative possibilities for your web interfaces. Combined with other modern CSS techniques, masking helps create memorable user experiences that set your web development projects apart from competitors.
Core CSS Mask Properties
mask-image
The primary property that specifies the mask source. Supports gradients, images, and SVG elements.
Code Example:
/* Gradient mask */
.mask-element {
mask-image: linear-gradient(to right, transparent, black);
}
/* Image mask */
.mask-element {
mask-image: url('shape-mask.png');
}
/* Multiple masks with composite */
.mask-element {
mask-image: url('primary-mask.png'), linear-gradient(black, transparent);
mask-composite: add;
}
mask-size and mask-position
Control the dimensions and placement of mask images, mirroring background-size and background-position behavior.
.mask-element {
mask-image: url('heart-shape.png');
mask-size: 200px 200px;
mask-position: center;
mask-repeat: no-repeat;
}
mask-mode
Determines whether masks use alpha or luminance mode. The default match-source automatically selects based on mask type--alpha for images and gradients, luminance for SVG <mask> elements.
.mask-element {
mask-mode: alpha; /* Use transparency */
mask-mode: luminance; /* Use brightness */
mask-mode: match-source; /* Auto-detect (default) */
}
mask-composite
Controls how multiple mask layers combine. Available values include add (overlay), subtract (remove first from second), intersect, and exclude.
.mask-element {
mask-image: url('layer1.png'), url('layer2.png');
mask-composite: add; /* Both layers visible */
mask-composite: subtract; /* layer2 removes from layer1 */
}
Creating Reveal Animations with Gradients
CSS gradients serve as powerful, lightweight mask sources that require no external images. Linear gradients create wipe effects, conic gradients produce radial reveals, and radial gradients generate circular or spotlight reveals.
Linear Wipe Reveals
The most common reveal pattern uses a linear gradient that animates from transparent to opaque:
.wipe-reveal {
mask-image: linear-gradient(to right, transparent 0%, black 100%);
mask-size: 200% 100%;
mask-position: left;
mask-repeat: no-repeat;
transition: mask-position 0.5s ease-out;
}
.wipe-reveal:hover {
mask-position: right;
}
This technique creates a smooth horizontal wipe effect. The mask-size at 200% means the visible portion occupies half the mask, and animating mask-position slides the reveal across the element.
Circular Reveal with Radial Gradient
Radial gradients enable center-out or edge-in circular reveals:
.circle-reveal {
mask-image: radial-gradient(circle, black 50%, transparent 50%);
mask-size: 200% 200%;
mask-position: center;
mask-repeat: no-repeat;
animation: reveal-circle 0.8s ease-out forwards;
}
@keyframes reveal-circle {
0% {
mask-size: 0% 0%;
}
100% {
mask-size: 200% 200%;
}
}
Conic Gradient Angle Reveals
Conic gradients create rotating reveal effects:
.conic-reveal {
mask-image: conic-gradient(black 0deg, transparent 0deg);
mask-size: 100% 100%;
animation: reveal-conic 1s ease-out forwards;
}
@keyframes reveal-conic {
0% {
mask-image: conic-gradient(black 0deg, transparent 0deg);
}
100% {
mask-image: conic-gradient(black 360deg, transparent 360deg);
}
}
Maximize performance by choosing the right properties to animate
GPU Acceleration
Animate mask-position and mask-size for smooth 60fps performance. These properties trigger compositing only, avoiding expensive layout recalculations.
Composite Modes
Use mask-composite to combine multiple masks on the GPU layer, reducing the number of composited layers the browser must process.
Reduced Motion
Respect user preferences with prefers-reduced-motion media queries. Disable or simplify animations for users who experience motion sensitivity.
Progressive Enhancement
Use @supports to detect mask support. Provide graceful fallbacks where masked elements display fully on unsupported browsers.
Advanced: Image-Based Mask Animations
External images serve as precise shape masks when they contain transparency. PNG masks work well for irregular shapes, while SVG masks offer resolution-independent precision and animation capabilities.
PNG Shape Masks
Transparent PNGs define exact reveal boundaries:
.shape-mask {
mask-image: url('star-mask.png');
mask-size: contain;
mask-repeat: no-repeat;
mask-position: center;
mask-mode: alpha;
}
For animated reveals, combine PNG masks with mask-size or mask-position animations to create expanding or sliding shape effects.
SVG Masks
SVG masks provide vector precision and can be animated directly:
<svg width="0" height="0">
<mask id="svg-mask">
<rect width="100%" height="100%" fill="black"/>
<circle cx="50%" cy="50%" r="0" fill="white">
<animate attributeName="r" from="0" to="100" dur="0.5s" fill="freeze"/>
</circle>
</mask>
</svg>
<style>
.svg-masked {
mask: url(#svg-mask);
}
</style>
This approach animates the SVG mask itself, with the CSS element reflecting the changes.
When implementing complex mask animations, consider partnering with experienced web development professionals who understand both the creative and performance implications of these techniques.
Common Use Cases and Patterns
Hero Section Image Reveals
Create dramatic entry animations for hero images:
.hero-image {
mask-image: linear-gradient(to bottom, black 50%, transparent 100%);
mask-size: 100% 200%;
mask-position: top;
animation: hero-reveal 1.2s ease-out forwards;
}
@keyframes hero-reveal {
0% {
mask-position: top;
}
100% {
mask-position: center;
}
}
Card Hover Reveals
Interactive cards with masked overlay reveals:
.card {
position: relative;
overflow: hidden;
}
.card-overlay {
position: absolute;
inset: 0;
background: linear-gradient(to top, rgba(0,0,0,0.8), transparent);
mask-image: linear-gradient(to bottom, black 0%, transparent 100%);
mask-size: 100% 200%;
mask-position: bottom;
transition: mask-position 0.4s ease;
}
.card:hover .card-overlay {
mask-position: top;
}
Loading and Progress Indicators
Use masks for creative loading states:
.loading-mask {
mask-image: conic-gradient(black 0%, transparent 0%);
animation: load-spin 1s linear infinite;
}
@keyframes load-spin {
to {
mask-image: conic-gradient(black 100%, transparent 100%);
}
}
Browser Support and Fallbacks
CSS masking has broad support across modern browsers:
| Browser | Version | Support |
|---|---|---|
| Chrome | 120+ | Full |
| Firefox | 53+ | Full |
| Safari | 9.1+ | Full |
| Edge | 120+ | Full |
For older browser support, use feature detection:
@supports (mask-image: linear-gradient(black, transparent)) {
.mask-element {
mask-image: linear-gradient(to right, transparent, black);
}
}
For browsers without mask support, consider fallback styling or progressive enhancement where masked elements gracefully degrade to fully visible states.
Want to explore more advanced CSS animation techniques? Check out our guide on things you can do with CSS today to expand your frontend toolkit.
Frequently Asked Questions
What is the difference between CSS masking and clipping?
CSS clipping uses a single path to either fully show or fully hide areas of an element--no partial transparency. Masking, on the other hand, uses the alpha transparency or luminance of a mask image to create nuanced visibility levels, allowing for soft edges and smooth transitions.
Which CSS mask properties are most performant to animate?
mask-position and mask-size are the most performant properties to animate because they trigger compositing only. Avoid animating mask-image with gradient changes, which triggers layout recalculations and can cause janky animations.
Should I use alpha or luminance masks?
Use alpha masks when you only care about transparency values--this is the default for most use cases. Use luminance masks when you want brightness to affect opacity, which is common when working with SVG masks that use grayscale values for precision.
How do I create a smooth reveal animation?
For smooth reveals, use mask-size or mask-position animations with CSS transitions or keyframes. The key is ensuring your mask gradient transitions smoothly from transparent to opaque or vice versa. Test on actual devices to verify 60fps performance.
Can I animate multiple masks together?
Yes, use the mask-composite property to control how multiple mask layers combine. Values include add (overlay), subtract, intersect, and exclude. Multiple masks can create complex reveal effects while remaining performant on modern browsers.
Sources
- MDN Web Docs - Introduction to CSS Masking - Official documentation for all CSS mask properties and concepts
- MDN Web Docs - Mask Properties - Detailed reference for mask-size, mask-position, mask-repeat, mask-clip, and mask-composite
- Smashing Magazine - CSS Masking for Animations - Creative animation techniques using CSS masks
- Natclark - How to Mask Images on Websites - Practical masking guide with gradient techniques