CSS Masks and Clip Path
clip-path for shapes and mask-image for alpha/luminance cutouts — differences, animation notes, and accessibility caveats.
- css
- masks
- clip-path
clip-path restricts the painted area of an element to a geometry (circle, polygon, path, box). mask-image (and longhands) use an image’s alpha or luminance to hide parts of the element — more like Photoshop masks. Both can create non-rectangular UI; neither is a substitute for semantic structure.
Docs: MDN clip-path, MDN CSS masking.
clip-path shapes
.avatar {
clip-path: circle(50%);
}
.ticket {
clip-path: polygon(
0 0,
100% 0,
100% 100%,
70% 100%,
65% 90%,
60% 100%,
0 100%
);
}
.hero-slash {
clip-path: polygon(0 0, 100% 0, 100% 85%, 0 100%);
}
.fade-edge {
clip-path: inset(0 0 0 0 round 1rem); /* rounded rect clip */
}
clip-path also accepts url(#svgClip) referencing an SVG <clipPath>.
Hit-testing: in modern browsers, pointer events generally follow the visible region for clip-path — still verify for your target engines when building custom controls.
mask-image
.scroll-hint {
mask-image: linear-gradient(to bottom, black 60%, transparent);
-webkit-mask-image: linear-gradient(to bottom, black 60%, transparent);
}
.icon-gradient {
background: linear-gradient(135deg, #0b6bcb, #c45c26);
mask-image: url("/icons/star.svg");
mask-size: contain;
mask-repeat: no-repeat;
mask-position: center;
-webkit-mask-image: url("/icons/star.svg");
/* same size/repeat/position for -webkit- if needed */
}
By default many engines use alpha masking; mask-mode / mask-type control luminance vs alpha for SVG masks.
clip-path vs mask — pick
| Need | Prefer |
|---|---|
| Simple CSS shapes, polygons | clip-path |
| Soft feathered edges, gradient fade | mask-image |
| Reuse complex SVG outline | Either SVG clip or mask |
| Animate shape morph | clip-path with interpolable polygons (careful) |
| Reveal with soft brush | mask |
/* Soft reveal */
.reveal {
mask-image: linear-gradient(90deg, black 0%, black 40%, transparent 70%);
}
Stacking and overflow
Clipped/masked content can still affect layout size — the box doesn’t shrink to the visible polygon unless you change dimensions. Overflow and shadows may be clipped too (box-shadow often disappears under clip-path — use filter: drop-shadow instead).
.avatar {
clip-path: circle(50%);
filter: drop-shadow(0 2px 6px rgb(0 0 0 / 0.25));
}
Accessibility
- Decorative clipping is fine; don’t hide live text that users need with a mask that fades content unreadably.
- Focus rings can look cut off — provide
outline-offsetor a parent ring. - Screen readers still read full text nodes even if visually masked — good for SR, bad if you “hide” secrets only visually.
Interview out-loud
“clip-path cuts an element to a geometric path. Masks use images or gradients to control transparency per pixel. I use clip-path for hard shapes like avatars and heroes, masks for soft fades. Layout box size doesn’t automatically equal the visible shape, and box-shadow often needs to become drop-shadow.”
Footguns
- Non-interpolable polygon point counts in animations — janky morphs.
- Forgetting
-webkit-mask properties where still required. - Clipping focus indicators.
- Huge SVG masks on many list items — paint cost.
- Assuming clipped content isn’t focusable/readable by AT.
SVG clipPath reference
<svg width="0" height="0" aria-hidden="true">
<defs>
<clipPath id="blob" clipPathUnits="objectBoundingBox">
<path d="M0.5,0 Q1,0.3 0.8,0.8 Q0.5,1 0.2,0.8 Q0,0.3 0.5,0" />
</clipPath>
</defs>
</svg>
.hero-photo {
clip-path: url(#blob);
}
objectBoundingBox units (0–1) scale with the element — usually what you want for responsive media. User-space units need careful sizing.
Performance
Animating clip-path polygons can be cheaper than animating layout, but complex paths still cost paint. Prefer transform/opacity for continuous motion; use clip morphs for short state changes. Masks with large blur-like gradients are similar in cost to heavy filters — profile on mid-tier mobile.
Related
- CSS filters and backdrop-filter
- object-fit and aspect-ratio
- blend-mode basics
- Outline vs border for focus
Further reading
Related guides
- Accent Color and Form ControlsUse accent-color to theme native checkboxes, radios, ranges, and progress — what it paints, what it skips, and when to custom-style instead.
- Auto-fit vs Auto-fillauto-fit collapses empty tracks; auto-fill keeps them. Use both with minmax for responsive card grids without media-query soup.
- BEM Naming MethodologyBlock, Element, Modifier naming for CSS — how it limits specificity wars, what to name, and when utility or CSS modules beat strict BEM.
- blend-mode Basicsmix-blend-mode vs background-blend-mode — how pixels combine, isolation, and the stacking/readability traps in product UI.
- box-sizing border-boxWhy border-box makes width include padding and border, the global reset pattern, and the layout bugs content-box still causes.