filter
A filter applies to the element and everything inside it, including its children and its text. That is often the surprise: a blur on a card blurs the card's text too.
filter: blur(8px);
filter: brightness(1.2);
filter: contrast(1.15);
filter: saturate(0.4);
filter: grayscale(1);
filter: sepia(0.3);
filter: hue-rotate(30deg);
filter: invert(1);
filter: opacity(0.6);
filter: drop-shadow(0 8px 16px rgb(0 0 0 / .3));
/* they compose, left to right */
filter: saturate(1.1) contrast(1.05) brightness(0.96);
drop-shadow versus box-shadow
For a transparent PNG or an inline SVG, box-shadow draws a rectangle behind it and drop-shadow traces the shape. It is the only way to shadow something that is not a box.
/* follows the rectangular box */
box-shadow: 0 8px 16px rgb(0 0 0 / .3);
/* follows the actual opaque pixels — a PNG cut-out, an SVG icon, a clipped shape */
filter: drop-shadow(0 8px 16px rgb(0 0 0 / .3));
backdrop-filter
backdrop-filter filters what is behind the element rather than the element itself. It is the whole of the frosted-glass look.
.glass {
background: rgb(255 255 255 / .06);
backdrop-filter: blur(24px) saturate(160%);
border: 1px solid rgb(255 255 255 / .12);
box-shadow: inset 0 1px 0 rgb(255 255 255 / .11);
}
Every frame, the browser has to read back what is behind the element and blur it. One fixed header is fine. A backdrop-filter on a list of cards that scrolls will drop frames on a phone. And it needs something translucent in the background to be visible at all.
Blend modes
/* blend this ELEMENT with what is painted behind it in its stacking context */
.overlay { mix-blend-mode: multiply; }
/* blend an element's own background LAYERS with each other */
.hero {
background-image: url("/media/photo.jpg"), linear-gradient(#c2452d, #14161a);
background-blend-mode: luminosity;
}
.duotone {
background: linear-gradient(#f1521f, #1b2a6b);
}
.duotone img {
mix-blend-mode: luminosity;
opacity: 0.9;
}
| Mode | Does |
|---|---|
multiply | Darkens. White becomes transparent — good for ink on paper. |
screen | Lightens. Black becomes transparent — good for light leaks and glows. |
overlay / soft-light | Adds contrast, keeping highlights and shadows. |
luminosity | Takes the lightness of the top and the colour of the bottom — a duotone. |
difference | Inverts against the backdrop. The trick behind text that stays legible over anything. |
isolation
mix-blend-mode blends with everything behind the element in its stacking context — which can mean the whole page background. isolation: isolate on the parent creates a new stacking context so the blending stops there.
.card {
isolation: isolate;
}
.card .tint {
mix-blend-mode: multiply;
}
clip-path
Anything outside the shape is not painted and not clickable. A clip-path also flattens 3D transforms on the same element.
clip-path: inset(10% 20% round 12px);
clip-path: circle(50% at 50% 50%);
clip-path: ellipse(40% 30% at 50% 40%);
clip-path: polygon(0 0, 100% 0, 100% 80%, 0 100%); /* an angled bottom edge */
/* animatable, as long as both ends have the same shape function and point count */
.reveal { clip-path: inset(0 100% 0 0); transition: clip-path 600ms ease-out; }
.reveal.in { clip-path: inset(0 0 0 0); }
mask
A mask uses the alpha of the mask image: opaque areas show, transparent areas hide. Unlike an overlay it works over any background, because it removes pixels rather than painting on top of them.
.fade-bottom {
mask-image: linear-gradient(#000 70%, transparent);
}
/* a spotlight that follows a custom property */
.lens {
mask-image: radial-gradient(circle 12rem at var(--mx, 50%) var(--my, 50%), #000 60%, transparent);
}
What each one costs
filterandmask— paint, usually on the GPU. Fine on small or few elements.backdrop-filter— read-back plus blur every frame. Use once or twice per page, on something that does not move much.mix-blend-mode— forces the browser to keep the backdrop available; it disables some compositing optimisations.- All of them create a stacking context, and
filteralso creates a containing block for fixed children. - Animating
filter: blur()is one of the most expensive things you can do. Animate opacity between a blurred and an unblurred copy instead.