Guides/ CSS & Images
auto_fix_high

CSS Photo Filters Guide: Instagram-Style Effects with filter()

The CSS filter property applies Photoshop-style effects to images with a single line: grayscale, sepia, blur, contrast, brightness. This guide covers every filter function, Instagram-style preset combinations, and the often-confused difference between filter and backdrop-filter.

April 2026 · 7 min read

Filter Functions Reference

FunctionRangeEffect
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 10 = color, 1 = black and white
sepia()0 to 1Warm brown tint, vintage feel
hue-rotate()0deg to 360degShifts color wheel by degree
invert()0 to 1Inverts colors (photo negative)
opacity()0 to 1Transparency (prefer opacity property)
blur()0px to ∞Gaussian blur, affects sharpness
drop-shadow()shadow paramsLike 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: filter when 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-filter for 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 filter property 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-filter prefix for Safari, or (3) the parent has overflow: hidden with 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 use clip-path or masks to reveal different filtered layers, or use Canvas/SVG for true per-pixel control.

Free reference

The 47 Tools Cheat Sheet

One printable page with every tool on this site, what it does, and when to reach for it. Free. It asks for an email so Gumroad can send you the file, unlike the tools themselves.