CSS Masks Are Better Than Editing a Fade Into an Image
A fade baked into an image works on exactly one background. A CSS mask keeps the source image intact and decides which pixels should be visible when the page is rendered.
That makes masks useful for soft edges, scroll hints, cutouts, and one-colour icons. The MDN CSS masking guide covers the complete set of properties.
Start with an alpha fade
.photo {
mask-image: linear-gradient(
to bottom,
black 70%,
transparent
);
}
With the normal alpha-mask behaviour, opaque pixels reveal the element and transparent pixels hide it. The colour black is not painted onto the photo; only its alpha matters here.
The same technique can hint that a horizontal row continues:
.logo-row {
overflow-x: auto;
mask-image: linear-gradient(
to right,
transparent,
black 2rem,
black calc(100% - 2rem),
transparent
);
}
Keep another visible cue for scrolling. A fade is decoration, not an instruction manual.
Use an SVG as a recolourable icon
A mask supplies the shape while the background supplies the colour:
.icon {
width: 2rem;
height: 2rem;
color: red;
background: currentColor;
mask: url("/icons/search.svg") center / contain no-repeat;
}
This is handy for a monochrome icon that should follow text colour. It is a poor fit for a multicolour illustration, because the mask keeps visibility information rather than the image’s original paint.
The longhand version is easier to debug:
.logo-shape {
mask-image: url("/mask.svg");
mask-repeat: no-repeat;
mask-position: center;
mask-size: contain;
background: blue;
}
Masking changes paint, not layout
The element still owns its rectangular box even where the mask makes it invisible. Test pointer targets and keyboard focus if the masked element is interactive.
I also avoid using a mask to carry essential information. A missing decorative fade is harmless; a missing control is not.
Make the effect optional
.photo {
display: block;
}
@supports (mask-image: linear-gradient(black, transparent)) {
.photo {
mask-image: linear-gradient(black 80%, transparent);
}
}
For a hard circle, border-radius is simpler. For a hard polygon, clip-path usually reads better. I reach for a mask when partial transparency is the actual effect—not merely because the property can do more.