The ten filter functions
filter applies graphical effects to an element and all its children, chaining space-separated functions:
| Function | Does |
|---|---|
blur(px) | Gaussian blur |
brightness(%) | Lighten/darken (100% = normal) |
contrast(%) | Tonal range |
grayscale(%) | Desaturate to gray |
saturate(%) | Color intensity |
hue-rotate(deg) | Shift colors on the wheel |
invert(%) | Invert colors |
sepia(%) | Warm brown tone |
opacity(%) | Transparency |
drop-shadow() | Shadow following the alpha shape |
Most are cheap color-matrix operations that run per-pixel on the GPU; blur() is the expensive one because it samples neighboring pixels, so large blur radii on big elements can drop frames.
filter vs backdrop-filter
A crucial distinction: filter affects the element and its content, while backdrop-filter affects the area behind the element. Want a frosted-glass panel where the background blurs but the panel’s text stays sharp? That’s backdrop-filter: blur(10px), not filter. Use filter for image and content effects; backdrop-filter for glassmorphism overlays and modal scrims. (The Glassmorphism Generator is built around backdrop-filter.)
Side effects to plan around
Two behaviors catch people out:
- It affects all children — there’s no way to exclude a child from a parent’s
filter. To filter only a background, apply the filter to a::before/::afterpseudo-element behind the content, or usebackdrop-filteron an overlay. - It creates a stacking/containing context — which breaks
position: fixeddescendants (see FAQ) and can changez-indexbehavior. Keep fixed/sticky elements out of filtered ancestors.
A handy recipe
A quick approximate dark-mode for images: filter: invert(1) hue-rotate(180deg) inverts light/dark while rotating the hue back so colors stay roughly correct. Filters are non-destructive and reversible (they don’t touch the source file), GPU-accelerated, and free of server processing — tune blur, brightness, contrast, and the rest with the live preview, mindful that function order changes the outcome.