CSS Masking: How to Use Masks in Web Design
Learn how CSS masks control visibility with gradients, images, and SVG, when to use alpha or luminance, and how to troubleshoot common masking problems.
CSS masking controls which parts of an element are visible and how opaque they appear. Opaque mask areas reveal the element, transparent areas hide it, and partially transparent areas reveal it with reduced opacity. Use mask-image with a gradient for a quick fade, a transparent image for a custom silhouette, or an SVG mask for a reusable vector design. Choose clip-path instead when you only need a hard-edged shape.
This guide covers CSS mask sources, alpha and luminance modes, SVG, layers and compositing, practical examples, browser support, troubleshooting, and performance. The examples use standard CSS masking properties described in the MDN introduction to CSS masking.
1. The smallest useful CSS mask
A gradient mask is often the simplest way to fade an image or other element. In alpha mode, the gradient’s opacity determines visibility; its color does not matter.
.fade-image {
mask-image: linear-gradient(to bottom, black 70%, transparent 100%);
mask-mode: alpha;
}
Apply it to an element:
<img class="fade-image" src="landscape.jpg" alt="Mountain landscape">
The image remains fully visible through the opaque upper portion and fades toward the transparent bottom. For a horizontal fade, change the direction to to right. To fade both ends, place transparent stops at both ends and an opaque stop in the middle:
.fade-edges {
mask-image: linear-gradient(to right, transparent, black 20%, black 80%, transparent);
mask-mode: alpha;
}
2. Choose a mask source
A mask source can be a CSS gradient, a raster image such as PNG or JPEG, or an SVG <mask>. The source you choose determines how you prepare the artwork and whether alpha or brightness controls the result.
CSS gradients
Gradients work well for fades, vignettes, and geometric transitions without a separate asset. This circular gradient reveals the center and hides the outside:
.spotlight {
mask-image: radial-gradient(circle, black 55%, transparent 72%);
mask-mode: alpha;
}
Raster images
A transparent PNG can provide a custom silhouette. In alpha mode, opaque pixels reveal the element and transparent pixels hide it. Partially transparent pixels produce partial visibility. JPEG has no transparency channel, so use it only when luminance behavior is appropriate or when the source is otherwise prepared for that purpose.
.masked-photo {
mask-image: url("/assets/shape-mask.png");
mask-mode: alpha;
mask-repeat: no-repeat;
mask-position: center;
mask-size: contain;
}
SVG masks
SVG masks are useful for scalable vector artwork and reusable shapes. An SVG source can be referenced by URL or by an inline fragment. For a URL source, make sure the SVG and its mask definition are served successfully:
.masked-by-svg {
mask-image: url("/assets/masks.svg#soft-shape");
mask-mode: alpha;
mask-repeat: no-repeat;
mask-position: center;
mask-size: 100% 100%;
}
An SVG <mask> source can default to luminance through its source mode. If the design depends on alpha instead, set the mode explicitly in CSS or configure the SVG mask’s mask-type. Explicit mode avoids relying on an implicit default. See MDN’s mask-image reference for source behavior and restrictions.
3. Alpha versus luminance
Mask mode tells the browser how to turn the source into opacity:
| Mode | What controls visibility | Useful for |
|---|---|---|
alpha |
The source’s transparency. Opaque reveals; transparent hides; partial alpha partially reveals. | CSS gradients and transparent PNG or SVG artwork. |
luminance |
Brightness combined with alpha. Brighter areas reveal more; darker areas reveal less. | Fully opaque grayscale mask artwork, such as white-on-black source images. |
match-source |
Uses the mode indicated by the source. Raster and gradient image sources typically resolve to alpha; SVG masks can default to luminance. | When the source’s own mode is intentional and understood. |
For a gradient, black and transparent are both useful in alpha mode: black is opaque, while transparent has zero alpha. The color of an opaque pixel does not change alpha-mode visibility. For luminance, source brightness matters, so white reveals more than black when both pixels are opaque.
/* Make the intended interpretation explicit. */
.alpha-mask {
mask-image: url("/assets/transparent-shape.png");
mask-mode: alpha;
}
.luminance-mask {
mask-image: url("/assets/grayscale-mask.png");
mask-mode: luminance;
}
When an SVG mask seems inverted or unexpectedly invisible, verify both its pixel colors and the selected mode. The MDN property reference explains how source type affects the default mode.
4. Size, position, repeat, and clip a mask
Mask layers have properties for sizing, positioning, repetition, and clipping, much like background layers. These let you align a source to an element, tile it, or constrain the area where it applies. For example:
.pattern-mask {
mask-image: url("/assets/dots.png");
mask-mode: alpha;
mask-size: 48px 48px;
mask-position: center;
mask-repeat: repeat;
}
Use mask-size: cover or contain when the source should scale to the element, and set mask-repeat: no-repeat for a single instance. With multiple comma-separated sources, corresponding values in layer properties are assigned by position. A none source still occupies a layer position, so it can affect how the lists match.
MDN’s mask properties guide describes the layer properties and list matching.
5. Combine mask layers
Multiple mask images can be stacked as comma-separated layers. mask-composite controls how a layer combines with the layers below it. The operators are add, subtract, intersect, and exclude. Order matters, especially with subtraction and intersection, so start with two layers and verify the result before adding more.
.cutout {
mask-image:
radial-gradient(circle at 30% 35%, black 0 18%, transparent 19%),
linear-gradient(black, black);
mask-mode: alpha, alpha;
mask-composite: subtract;
}
This example stacks a circular mask above a fully opaque base layer and subtracts the top layer, creating a circular transparent cutout in the base. If the outcome differs from what you expect, inspect the layer order and operator together. Check the exact browser support for mask-composite and related properties rather than assuming every masking feature has identical support. See MDN’s mask-composite reference.
6. Masking versus clipping
Use clip-path for a simple, hard-edged shape when each point is either fully visible or fully hidden. Use a mask for soft edges, partial transparency, luminance-based opacity, or layered image effects.
| Need | Prefer | Reason |
|---|---|---|
| Hard-edged circle, polygon, or inset | clip-path |
Direct way to define a binary shape. |
| Fade or feathered edge | CSS mask | Can express partially visible pixels. |
| Silhouette from transparent artwork | Alpha mask | Uses source transparency as the visibility map. |
| Grayscale artwork controls opacity | Luminance mask | Uses brightness as well as alpha. |
| Several visual layers interact | Mask layers and compositing | Combines sources using explicit operators. |
MDN notes that clipping can perform better when a basic shape is all that is needed, and that simple shapes can be easier to interpolate. Both clipping and masking affect rendering after the element’s base styles; MDN describes the order as filters, clipping, masking, then opacity. Read MDN’s CSS masking guide when choosing between them.
7. Practical patterns
Fade the bottom of a card image
.card-image {
display: block;
width: 100%;
height: 18rem;
object-fit: cover;
mask-image: linear-gradient(to bottom, black 65%, transparent 100%);
mask-mode: alpha;
}
Reveal text through a moving gradient
.gradient-text {
color: transparent;
background: linear-gradient(90deg, #111 0 35%, #aaa 50%, #111 65%);
background-clip: text;
-webkit-background-clip: text;
}
This text effect uses background clipping rather than mask-image. For an element-wide reveal animation, animate a mask gradient or its position instead; test the result on your target browsers.
Keep a decorative mask from blocking interaction
If a separate decorative layer sits above interactive content, make that layer ignore pointer input:
.decorative-overlay {
pointer-events: none;
}
A mask on an element changes its rendered visibility; it does not remove the element from layout. Consider keyboard focus and accessible names separately from visual appearance. If masked content is essential, ensure it remains understandable and usable without relying on the visual effect.
8. Browser support and compatibility
MDN marks mask-image widely available, with browser availability since December 2023. That summary does not mean every mask property, composition operator, SVG source, or edge case behaves identically in every browser. Review compatibility for the exact properties used and check the browsers your project supports. MDN’s current compatibility data for mask-image is a useful starting point.
For production work, verify the final result in target browsers, especially when using multiple layers, external SVG references, or compositing. Provide a sensible unmasked or clipped appearance when the effect is decorative and a browser does not support the required behavior.
9. Troubleshooting CSS masks
| Symptom | Likely cause | Fix |
|---|---|---|
| The whole element disappears | The mask source failed to load, is unsupported, or resolves to transparent black. | Check the URL and network response, confirm the file is valid, and temporarily remove mask-image to isolate the problem. |
| The mask appears inverted | The source mode is wrong, or the luminance artwork has the opposite brightness from what you intended. | Set mask-mode explicitly. For alpha, inspect transparency; for luminance, inspect the grayscale values. |
| A gradient shows no fade | The mask may not cover the expected axis or stops, or the fade is outside the element’s visible area. | Use a direction that matches the desired fade, inspect stop positions, and temporarily use obvious opaque and transparent stops. |
| An SVG mask works locally but not when deployed | The external asset may have a wrong URL, fail to load, or be blocked by origin or HTTP/HTTPS restrictions. | Verify the deployed URL and response, use compatible origins and schemes, and inspect the browser console and network panel. |
| A mask layer is offset or tiled unexpectedly | Default sizing, positioning, or repetition is being applied. | Set mask-size, mask-position, and mask-repeat explicitly for each layer. |
| Composition produces a surprising cutout | Layer order or operator behavior differs from the mental model. | Reduce the example to two layers, label their order in comments, and test one operator at a time. |
| The effect differs between browsers | A less commonly used mask property or source behavior has varying support. | Check compatibility for every property used and choose a simpler clip or fallback where the effect is nonessential. |
Image mask sources are subject to HTTP/HTTPS and CORS-related restrictions; local file:// URLs are not accepted as image values. A missing or unsupported mask image behaves like transparent black, which can hide the entire element. These behaviors are documented in the MDN mask-image reference.
10. Performance, reliability, and cost
CSS masks require no paid service or special runtime: gradients are declared in CSS, and image or SVG sources are ordinary page assets. Keep source files appropriately sized, avoid unnecessary layers, and prefer clip-path for a basic hard-edged shape. There is no universal performance number for a mask; rendering cost depends on the effect, source, browser, and page. Check the target experience rather than relying on a benchmark that does not match your page.
For reliability, ensure remote mask assets load over the right scheme and from an allowed origin. A broken mask source can make content disappear, so avoid making essential content depend only on an unverified external asset. Confirm behavior in the browsers that matter to your site.
11. Or skip the browser setup
If you need a screenshot of the finished page to document or review a masking effect, ScreenshotNeo can capture a URL with one GET request. The do-it-yourself approach above gives you full control over the browser and CSS; an API is useful when you need repeatable captures in a script or workflow.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for request options. Cookie banners, popups, and chat widgets are removed before the shot. Bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up for free and capture your first screenshots.
12. FAQ
Does a CSS mask change an element’s layout?
No. A mask controls rendered visibility; it does not resize or reposition the element in layout.
Can I use a mask on something other than an image?
Yes. A mask can affect an element’s rendered appearance, including text or other content, subject to the source and browser support.
Should a decorative mask be part of the content’s meaning?
Keep essential information available independently of a visual mask. Treat purely decorative effects as decoration and preserve the content’s accessible meaning.


