Skip to main content

CSS Filter Generator

Create CSS filter effects with blur, brightness, contrast, grayscale and more. Image-filter CSS in one click.

Reviewed by · Last reviewed

0px
100%
100%
0%
0deg
0%
100%
100%
0%
CSS
filter: none;

Operating the Filter Generator

  1. Move each slider - blur, brightness, contrast, grayscale, hue-rotate, invert, opacity, saturate, sepia - to apply the corresponding filter function. Each filter has a sensible default that represents a no-op; leaving it there excludes it from the output.
  2. Chain filters implicitly. Any slider that differs from its neutral value contributes to the final filter: f1(x) f2(y) string. Filters apply left-to-right, so grayscale(1) sepia(1) gives a warmer duotone than sepia(1) grayscale(1).
  3. Watch the preview image. The same filter stack is applied to a sample image and rendered through a plain style attribute - what you see is literally what the browser will paint in your production page.
  4. Hit "Reset All" to return every slider to its default (identity) value when you want to start from scratch.
  5. Copy CSS. Paste the filter declaration onto any HTML element - images, divs, videos, SVG, even inline text.

How the filter pipeline executes

CSS filter is defined in Filter Effects Module Level 1 and maps to a series of SVG-equivalent filter primitives (feGaussianBlur, feColorMatrix, feComponentTransfer, feOffset). When the browser sees filter: blur(4px) grayscale(1), it constructs an in-memory filter graph, rasterizes the element into an offscreen buffer, runs the filter primitives against that buffer in order, and composites the result back into the page. Every built-in function - blur, brightness, contrast, grayscale, hue-rotate, invert, opacity, saturate, sepia, and the shorthand drop-shadow - desugars to one of these primitives with preset arguments.

Critically, filters force the element onto its own compositor layer and render it offscreen before applying the filter, which has two consequences. First, filters are GPU-accelerated in every modern browser because the offscreen pass runs on the GPU. Second, the containing block for descendants changes: position: fixed children get caught by the filtered ancestor, a surprise that catches people out when migrating pages. Large blur radii are the expensive case - a 30px blur on a full-viewport element can drop animations to 30fps on mid-range mobile. Chrome DevTools\' Performance tab shows the cost under "Paint" and "Composite Layers" entries.

Real cases where filter earns its keep

  • Hero photo washes - combining brightness and saturate to tint a photo toward the brand palette without editing the source file.
  • Hover states on product images - a subtle brightness(1.05) or saturate(1.1) on hover signals interactivity without extra assets.
  • Disabled UI states using grayscale(1) opacity(0.6) instead of hand-crafted disabled styles on every control.
  • Blurred modal backdrops layered over page content (often combined with backdrop-filter).
  • Duotone hero imagery - grayscale(1) sepia(1) hue-rotate(200deg) gives you a blue duotone for free.
  • Print-safe versions - apply grayscale(1) inside a @media print rule to force monochrome printing of colorful infographics.

Edge cases and gotchas

  • position: fixed inside filtered elements stops being fixed. Filters create a containing block per Filter Effects Level 1, so fixed descendants scroll with the filtered ancestor. Move them out of the filtered subtree.
  • Blurred edges leak past the box. A 10px blur extends 10px in every direction; clipping with overflow: hidden cuts the leak but also cuts the blur itself, which usually looks worse than either extreme. Add padding to the filtered container, or accept the extended region.
  • Backdrop-filter is a different property. filter affects the element\'s own pixels; backdrop-filter affects what\'s behind the element. They take the same function syntax but have different compatibility profiles and often appear together on modals.
  • Hue-rotate past 360 wraps. hue-rotate(540deg) is equivalent to hue-rotate(180deg). This is expected but often surprises people animating rotation continuously - use 360deg as the upper bound for a single cycle.
  • Multiple invert() calls don\'t cancel perfectly. Because each filter runs on the rasterized output of the previous one, invert(1) invert(1) is close to but not identical to identity on anti-aliased edges. Avoid doubling filters that should cancel.
  • Text gets slightly softer under any filter. The offscreen rasterization at the element\'s paint resolution means sub-pixel text anti-aliasing is lost. Headings and body copy still read fine; thin serif fonts at small sizes may look marginally blurrier.

Spec and compatibility

CSS filter comes from the Filter Effects Module Level 1. It deliberately piggybacks on SVG filter primitives to avoid reinventing image-processing math, and every shorthand function is formally equivalent to a named combination. Browser support per caniuse.com/css-filters: Chrome 53+, Firefox 35+, Safari 9.1+, Edge 13+ - essentially universal since 2016. The unrelated backdrop-filter property has slightly narrower coverage - it needed -webkit- in Safari until 14. The spec also defines filter: url(#id) to reference an arbitrary SVG <filter>, which is how you apply custom feTurbulence, feMorphology, or Bezier-curve component transfers - things not expressible with the built-in shorthand functions.

CSS filter vs image-editing workflows

Most of what filter does can also be baked into image assets at export time from Figma or Photoshop. The live-filter approach wins when you need theming (dark-mode duotone via a single CSS variable), hover interactions, animation, or user-configurable effects. It loses when you need precise color science for print-bound imagery or consistent appearance across non-CSS viewers (RSS, AMP, email clients). For animated filter effects, filter with @keyframes is far cheaper than re-rendering an image on a canvas every frame, and it stays crisp at any DPR. For photographic-quality color grading, Adobe Camera Raw still produces better results. And if you need filters beyond the shorthand - selective color, tone curves, convolution blurs - fall through to an SVG <filter> with explicit feColorMatrix, which filter: url() will happily reference.

Frequently Asked Questions

What is the difference between filter and backdrop-filter?

<code>filter</code> applies image effects to the element's own pixels - its children, background, borders, and text. <code>backdrop-filter</code> applies the same functions to whatever is painted behind the element, creating the iOS-style frosted glass look. They take the same function list but compose differently. Browser support diverges: <code>filter</code> is universal, <code>backdrop-filter</code> needed <code>-webkit-</code> in Safari until 14.

Why do my fixed-position children start moving when I apply filter?

Because Filter Effects Level 1 says any element with a non-<code>none</code> filter establishes a new containing block for its <code>position: fixed</code> descendants. The browser needs a consistent coordinate system to rasterize the filter input, so it re-roots the descendants to that filtered box. The fix is to move the fixed element outside the filtered ancestor - usually to the <code>&lt;body&gt;</code> or a sibling container.

How expensive is filter: blur() on performance?

Gaussian blur is one of the more expensive filter primitives because its cost scales linearly with the blur radius and quadratically with the filtered area. A 4px blur on a 200x200 element is essentially free; a 30px blur on a full-screen element can drop frame rate 30-50% on mid-range mobile. Use small radii, small elements, or <code>will-change: filter</code> on elements that are filtered and animated.

Can I chain filters to create duotone effects?

Yes, and it's one of the most useful filter idioms. Start with <code>grayscale(1)</code> to strip color, then <code>sepia(1)</code> to push toward warm brown, then <code>hue-rotate()</code> to shift the brown into any color you want - <code>180deg</code> gives teal, <code>240deg</code> blue, <code>340deg</code> magenta. Follow with <code>saturate(2)</code> to intensify the tint. Order matters because each filter operates on the output of the previous one.

Does this tool send my image through a server?

No. The sample image is a static asset bundled with the page, and the filter string is applied via a plain <code>style="filter: ..."</code> attribute on a local <code>&lt;img&gt;</code> element. The Preact component stores all slider values in local state and regenerates the CSS string on each change. There is no upload step and no server-side rendering.

What does hue-rotate actually rotate?

It rotates the hue channel of each pixel around the color wheel by the specified angle. Red at 0 becomes yellow at 60, green at 120, cyan at 180, blue at 240, magenta at 300, and back to red at 360. Neutral grays are unaffected because they have no hue, which is why applying <code>hue-rotate</code> to a grayscale photo has no visible effect - you need some saturation first.

Can I animate filter values smoothly?

Yes, every filter function value is animatable. Transitions between different filter lists only interpolate cleanly when the lists have the same functions in the same order - <code>filter: blur(4px)</code> to <code>filter: blur(8px)</code> interpolates linearly, while <code>filter: blur(4px)</code> to <code>filter: grayscale(1)</code> falls back to a discrete swap. Always pad both keyframes with the full function list using identity values where needed.

Does filter work on text?

Yes, you can apply <code>filter</code> to any element including text containers. <code>filter: blur(2px)</code> on a heading blurs the glyphs themselves. Text sub-pixel antialiasing is lost when an element is rasterized for filtering - the text stays legible but loses a hair of crispness. For shadowed text use <code>text-shadow</code>.

Are there filter effects I cannot get from the shorthand functions?

Plenty - morphology, convolution blurs, selective color, tone curves, displacement maps. For those, reference an SVG <code>&lt;filter&gt;</code> via <code>filter: url(#myFilter)</code>. The SVG primitives cover most image-editor effects.

Is this an image filter CSS tool?

Yes. "Image filter css", "css image filter", "css blur", "css brightness contrast" and "css filter effect" are common ways people search for this. Every slider on the page maps to one of the nine standard <code>filter()</code> shorthand functions, and the output is a single ready-to-paste <code>filter:</code> declaration that works on <code>&lt;img&gt;</code>, <code>&lt;video&gt;</code>, <code>&lt;div&gt;</code> backgrounds, inline SVG and more. If you need the frosted-glass "blur what is behind" effect rather than blurring the element itself, use the <a href="/tools/glassmorphism-generator/">glassmorphism generator</a> which drives <code>backdrop-filter</code>.

More CSS & Design