Filter Functions Reference
| Function | Range | Effect |
|---|---|---|
brightness() | 0 to ∞ (1 = original) | Darker below 1, brighter above |
contrast() | 0 to ∞ (1 = original) | Flatter below 1, punchier above |
saturate() | 0 to ∞ (1 = original) | 0 = grayscale, 2 = oversaturated |
grayscale() | 0 to 1 | 0 = color, 1 = black and white |
sepia() | 0 to 1 | Warm brown tint, vintage feel |
hue-rotate() | 0deg to 360deg | Shifts color wheel by degree |
invert() | 0 to 1 | Inverts colors (photo negative) |
opacity() | 0 to 1 | Transparency (prefer opacity property) |
blur() | 0px to ∞ | Gaussian blur, affects sharpness |
drop-shadow() | shadow params | Like box-shadow but respects image transparency |
Combining Filters
Apply multiple filters by space-separating them. Order matters — filters apply left to right:
img {
filter: contrast(1.1) brightness(1.05) saturate(1.2);
}
/* Order matters: grayscale after hue-rotate vs before */
.a { filter: hue-rotate(90deg) grayscale(1); } /* gray result */
.b { filter: grayscale(1) hue-rotate(90deg); } /* still gray */
Instagram-Style Presets
Classic filter recipes you can apply directly:
Clarendon (Cool, Punchy)
.clarendon {
filter: contrast(1.2) saturate(1.35);
}
Gingham (Soft, Vintage)
.gingham {
filter: brightness(1.05) hue-rotate(-10deg) sepia(0.04);
}
Moon (Cool Black & White)
.moon {
filter: grayscale(1) contrast(1.1) brightness(1.1);
}
Lark (Bright, Desaturated Greens)
.lark {
filter: brightness(1.1) contrast(0.95) saturate(1.15);
}
Reyes (Dusty, Faded)
.reyes {
filter: sepia(0.22) brightness(1.1) contrast(0.85) saturate(0.75);
}
Juno (Warm, Vivid)
.juno {
filter: contrast(1.15) saturate(1.4) hue-rotate(-5deg);
}
Hover Effects with filter()
/* Color on hover, grayscale at rest — portfolio classic */
.gallery img {
filter: grayscale(1);
transition: filter 0.4s ease;
}
.gallery img:hover {
filter: grayscale(0);
}
/* Blur on hover for out-of-focus effect */
.blurrable {
transition: filter 0.3s;
}
.blurrable:hover {
filter: blur(8px);
}
/* Brightness pulse on card hover */
.card:hover img {
filter: brightness(1.1) saturate(1.1);
}
filter vs backdrop-filter
Two different properties for two different jobs:
filter— applies effects to the element itself. The element and everything inside it gets filtered.backdrop-filter— applies effects to whatever is behind the element, visible through its transparent/semi-transparent background. The element itself is not filtered.
/* Glassmorphism panel — blur what's behind the element */
.glass {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(16px) saturate(1.5);
-webkit-backdrop-filter: blur(16px) saturate(1.5);
border: 1px solid rgba(255, 255, 255, 0.2);
}
/* Darkened image with text overlay readable */
.hero {
position: relative;
}
.hero::before {
content: '';
position: absolute;
inset: 0;
backdrop-filter: brightness(0.6);
}
backdrop-filter is what powers iOS-style glassmorphism. It needs a transparent or semi-transparent background to show the filtered backdrop through.
Performance Notes
- Most filters are GPU-accelerated — safe to use on large images and animate smoothly.
- blur() is expensive at large radii — 20px+ blur on a full-screen element can drop frame rate on mobile.
- backdrop-filter is heavier than filter — the browser must composite everything behind. Use sparingly on mobile.
- Combining filter with animations — stick to opacity and transform for transitions if possible; filter animations stress compositing.
- Add
will-change: filterwhen animating, but remove it after the animation ends (it reserves resources).
Browser Support
filter— supported in all browsers since 2015. Safe to use unconditionally.backdrop-filter— Chrome, Edge, Safari fully support. Firefox supports since 2022. Include-webkit-backdrop-filterfor older Safari.- SVG filters (referenced via
filter: url(#id)) — supported everywhere but harder to write. Built-ins cover most use cases.
Frequently Asked Questions
- Are CSS filters destructive?
- No — they apply at render time. The underlying image is untouched. Remove the
filterproperty and you're back to the original. This is the main advantage over server-side filtering. - Can I save a CSS-filtered image?
- Not directly from CSS — the filter is a display layer. To persist the filtered result, render the image to a Canvas with the same filter applied, then export the canvas. Most browser-based filter tools do this behind the scenes.
- Why does my backdrop-filter not work?
- Three common issues: (1) the element has a fully opaque background (no backdrop visible), (2) you forgot the
-webkit-backdrop-filterprefix for Safari, or (3) the parent hasoverflow: hiddenwith rounded corners clipping the backdrop area. - Is there a way to get more control than built-in filters?
- Yes — use SVG filters via
filter: url(#my-filter)referencing an inline<filter>element. You can compose arbitrary matrix operations, displacement maps, and turbulence effects. Complex, but gives you Photoshop-level control. - Can I apply different filters to different parts of an image?
- Not with pure
filter— it applies to the whole element. You can useclip-pathor masks to reveal different filtered layers, or use Canvas/SVG for true per-pixel control.