Topic 10.4
Filters, Blend Modes and Masks
In one line
filter applies photo effects such as blur, grayscale and drop shadows to an element, backdrop-filter applies them to what's behind it, mix-blend-mode mixes its colours with the content underneath, and clip-path and mask hide parts of it with a shape or an image.
Think of it like this
Things you put in front of a camera. A filter is a coloured or frosted lens on the camera: everything you photograph through it looks blurred or black-and-white. Frosted glass in a bathroom window is a backdrop filter: the glass itself is clear-ish, but whatever is behind it looks blurry. Blending is like painting with see-through watercolours, where the colour underneath changes the colour you see. Clipping is cutting a photo into a circle with scissors, and a mask is a stencil you can spray through, where the paint fades at soft edges.
Words you'll meet
New words in this topic, in plain English. Come back here whenever one feels fuzzy.
- Filter function
- One effect like
blur()orgrayscale(), applied to the element's painted pixels. - Backdrop
- Whatever is painted behind an element: the page, images, other elements.
- Blend mode
- A rule for mixing two colours on top of each other, like
multiplyorscreen. - Alpha
- How opaque a pixel is, from fully transparent (0) to fully solid (1).
- Clip path
- A shape outside of which nothing of the element is drawn, with hard edges.
- Mask
- An image or gradient whose transparency decides how much of the element shows, so edges can be soft.
- Isolation
- Making a group, so blend modes inside it only mix with things in the group.
- Stacking context
- A group of layers painted together, so children can't be layered between outside elements (Topic 6.3).
Step by step
01Apply a filter
One property, a list of functions. Grey the image out and lower its brightness, for example to show a sold-out product. Hover removes the filter with a transition (filter functions interpolate when the lists match).
.product.sold-out img {
filter: grayscale(1) brightness(0.8);
transition: filter 0.3s;
}
.product.sold-out:hover img {
filter: grayscale(0) brightness(1);
}02Shadow the shape, not the box
An SVG star with a transparent background gets a square shadow from box-shadow. drop-shadow() follows its points.
.icon {
filter: drop-shadow(2px 4px 4px rgb(0 0 0 / 0.4));
}03Frost the glass
A semi-transparent panel over a busy background, with backdrop-filter. The fallback background stays readable in browsers that don't support it, so it degrades gracefully.
.glass {
background: rgb(255 255 255 / 0.55); /* readable even without blur */
backdrop-filter: blur(10px) saturate(1.4);
}04Blend text into an image
Big white heading text with mix-blend-mode: difference over a photo shows the photo's negative inside the letters. Put isolation: isolate on the hero so the text doesn't blend with the rest of the page.
.hero { isolation: isolate; }
.hero h1 {
color: white;
mix-blend-mode: difference;
}05Cut a shape, then fade an edge
clip-path cuts with scissors; mask-image uses a stencil with soft edges. Both leave the layout box alone.
.avatar { clip-path: circle(50%); }
.excerpt {
max-height: 6em;
overflow: hidden;
mask-image: linear-gradient(black 60%, transparent);
}Try it yourself
- 1
Swap the filter order
In the first example, give one picture
filter: sepia(1) hue-rotate(180deg)and anotherfilter: hue-rotate(180deg) sepia(1). Predict which one ends up brown (the second: sepia is applied last). - 2
Try every blend mode
In the third example, cycle
mix-blend-modethroughmultiply,screen,overlay,exclusionandluminosity. Then removeisolation: isolatefrom.heroand setbody { background: black; }: predict whether the heading changes (it can, because without isolation it may blend with more than the hero). - 3
Make a hexagon and test the click
In the fourth example, change
.trito a hexagon:polygon(25% 0, 75% 0, 100% 50%, 75% 100%, 25% 100%, 0 50%). Then change the JavaScript to test a point in its top-left corner. Predict the element it finds before you run.
Code & diagrams
One small "photo" (a sun over hills, drawn with gradients) through eight lenses. The computed `filter` keeps your list in order.
Preview
Console
Nothing logged yet.Expected console output
none
grayscale(1)
contrast(2) saturate(2)The image file is a transparent square with a star in it. `box-shadow` only knows the square; `drop-shadow()` uses the star's real pixels.
Preview
Console
Nothing logged yet.Remove `backdrop-filter` and the stripes show sharply through the panel. Change `difference` to `multiply`, `screen` or `overlay` and compare: white with `multiply` disappears entirely.
Preview
Console
Nothing logged yet.The clipped-away corner is not part of the element any more for clicks: `elementFromPoint` (what a click there would hit) finds the `.row` behind it. The layout box is unchanged. `circle(40%)` keeps its default centre (`at 50% 50%`), so the computed value leaves it out.
Preview
Console
Nothing logged yet.Expected console output
clip-path: circle(40%)
click at the centre hits: shape circle
click at the corner hits: row
layout width is still 80Break it on purpose
Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.
Break #1
backdrop-filter on an opaque background
Write .panel { background: white; backdrop-filter: blur(10px); }.
Break #2
A filter on a parent breaks a fixed header
Add filter: grayscale(1) to <main> for a "grey mode", where <main> contains a position: fixed header.
Break #3
A clip-path that eats the focus ring
Clip a <button> with clip-path: circle(50%) and tab to it with the keyboard.
Myth vs fact
Myth
filter: drop-shadow() and box-shadow are the same thing.
Fact
box-shadow shadows the box (and supports spread and inset). drop-shadow() shadows the painted pixels, so it follows transparent images and clipped shapes, but has no spread or inset.
Myth
Clipped-away parts of an element can still be clicked.
Fact
Hit-testing respects clip-path: clicks on the hidden part go to whatever is underneath. Masks are different: the spec doesn't require a mask to change hit-testing, so a fully masked, invisible area may still receive clicks. Don't rely on a mask to block clicks.
Myth
opacity: 0.5 and filter: opacity(0.5) are identical.
Fact
They look the same, but filter: opacity() sits in the filter list (so its order with other filters matters) and may be slower; opacity is the cheap, compositor-friendly one to animate.
Pro corner
Extra depth for experienced readers. New to this? Skip it for now and come back later.
- ▸
The painting order is: the element paints, then
filter, thenclip-pathandmask, thenopacity, and finally the result is blended with the backdrop usingmix-blend-mode. So adrop-shadow()is clipped by aclip-pathon the same element; to keep the shadow, put the clip on a child and the filter on the parent. - ▸
Blur cost grows with the blur radius and the area covered. Large
backdrop-filterregions (a sticky header over a scrolling page) are re-filtered every frame and are a common cause of scroll jank on mid-range phones; test on real devices and keep radii small. - ▸
filter,backdrop-filter,clip-pathandmaskinterpolate when their function lists match, so they can be transitioned and animated.clip-pathpolygons interpolate point by point only when both shapes have the same number of points. They usually need repaint work each frame, not just compositing, though browsers can accelerate some filters on the GPU. - ▸
In
forced-colorsmode (Windows High Contrast), browsers replace your colours with the user's system colours and drop shadows, so effects built from colour and shadow can vanish. Never put meaning only in a filtered or blended effect: make sure text stays readable without it (see Topic 11.7, Accessible CSS).
Remember this
- 1
filtertakes one or more filter functions and applies them to the element and everything inside it, after it's painted:blur(4px)(softens; the length is how far the blur spreads),brightness(1.2)(1 is unchanged),contrast(1.5),grayscale(1)(1 or100%is fully grey),sepia(1)(old-photo brown),saturate(2)(more vivid colour),hue-rotate(90deg)(shifts every colour around the colour wheel),invert(1)(a photo negative),opacity(0.5)anddrop-shadow(x y blur colour). Several functions are applied in order, left to right, sograyscale(1) sepia(1)differs fromsepia(1) grayscale(1).filter: url(#id)points to an SVG filter for effects CSS can't express. - 2
drop-shadow()differs frombox-shadow:box-shadowdraws a shadow of the element's rectangle (rounded byborder-radius), whiledrop-shadow()follows the actual shape of the painted pixels, including transparent parts of a PNG or SVG icon. It has no spread value and noinset, and it's usually slower, because the browser must blur the real pixel shape. - 3
backdrop-filter(Baseline 2024) applies the same functions to the content behind the element, inside the element's border box, giving the "frosted glass" look:background: rgb(255 255 255 / 0.4); backdrop-filter: blur(10px);. The element's own background must be at least partly transparent, or you can't see the effect. It's one of the most expensive effects in CSS, because the browser must re-blur whatever is behind the element whenever that changes (for example, every frame while scrolling). - 4
mix-blend-modedecides how an element's colours mix with whatever is painted below it.normalsimply covers it.multiplydarkens (like overlapping inks: white disappears),screenlightens (black disappears),overlayboosts contrast,differencesubtracts colours (white text over a photo becomes its negative), anddarken,lighten,color-dodge,color-burn,hard-light,soft-light,exclusion,hue,saturation,colorandluminositycover the rest.background-blend-modeblends an element's own background layers (a colour with a background image) instead.isolation: isolateon a parent creates a group, so children blend only with each other and the parent's background, not the whole page. - 5
clip-pathhides everything outside a shape, with hard edges:inset(10px round 12px)(a rectangle shrunk inwards, with rounded corners),circle(40%)orcircle(50px at 30% 40%),ellipse(60% 40%),polygon(50% 0, 100% 100%, 0 100%)(a triangle from points),path("...")(an SVG path) orurl(#clip). The hidden part is not painted and can't be clicked: clicks there go to whatever is behind. The layout box doesn't change; clip-path, like transform, only affects drawing. Shapes with the same number of points can be animated smoothly. - 6
mask-image(Baseline 2023) is a softer stencil. It takes an image or gradient, and each pixel's alpha (transparency) decides how much of the element shows: opaque means fully visible, transparent means hidden, half-transparent means half visible.mask-image: linear-gradient(black 70%, transparent)fades the bottom of a long text out. Masks have the same helper properties as backgrounds (mask-size,mask-repeat,mask-position), andmask-mode: luminanceuses brightness instead of alpha. Likeopacity < 1, afilter, amask, aclip-pathor a non-normalmix-blend-modecreates a stacking context (Topic 6.3);filterandbackdrop-filteralso become the containing block for fixed descendants.
Explain it without notes
What does filter do, and why does the order of filter functions matter?
When would you use drop-shadow() instead of box-shadow?
How does backdrop-filter differ from filter, and what does it need to be visible?
What is mix-blend-mode, and what problem does isolation: isolate solve?
Compare clip-path and mask-image.
Practice
Make every image inside .gallery grey and slightly dark, and show its real colours when hovered, with a 0.3s transition.
Make a .badge cut into a triangle pointing right, using clip-path.
Fade out the right-hand edge of a horizontally scrolling .chips row with a mask, so it hints there is more to scroll.
Trade-offs
- ↔
Filters and blends give image-editor effects without editing images, but they cost paint and GPU time on every change; prepare effects in the image itself when they never change.
- ↔
backdrop-filterlooks modern but is expensive and reduces contrast unpredictably over busy content; always keep a semi-opaque background so text stays readable. - ↔
clip-pathis cheap and animatable but hard-edged and clips outlines; masks are soft and flexible but don't affect clicks the same way and can be harder to debug.
Done when you can
I can combine filter functions and predict the effect of their order.
I can choose between
box-shadowanddrop-shadow().I can build a frosted-glass panel with a readable fallback.
I can use
mix-blend-modeand contain it withisolation: isolate.I can cut shapes with
clip-pathand fade edges withmask-image.I know these effects create stacking contexts, and some create containing blocks.