Frosted navigation bars and soft hero backgrounds both come down to the same function, blur(). Modals use it too, usually on the overlay. Where you put it decides what goes soft. filter: blur() softens the element itself, while backdrop-filter: blur() softens whatever sits behind a translucent element, and the browser does either one live, straight in CSS.
On ordering, the W3C Filter Effects Module Level 1 (2026) fixes the order of operations: the filter runs first, then clipping, masking and opacity, so those effects act on the already blurred result.
What is the CSS blur effect?
See the Pen
Animated CSS filter blur by yoichi kobayashi (@ykob)
on CodePen.
The browser applies a Gaussian blur while it renders, either to the element through filter or to what sits behind it through backdrop-filter. The source image never changes.
Both are CSS properties that take the same blur() function, so what gets blurred is the only real difference between them.
It also isn’t a shadow, even though the numbers look alike. The W3C Filter Effects draft notes that the standard deviation behind blur() is different from the blur radius in box-shadow, so the same number does not give the same spread.
How the blur radius works
The number inside blur() is the standard deviation of the Gaussian function. Bigger number, more neighboring pixels mixed in, softer image.
Real engines only approximate the curve. A note in the W3C Filter Effects Module Level 1 editor’s draft (22 September 2026 edition) says all major implementations used a three-pass box blur as of January 2024, and its formula works out to an extent of about 1.88 times the standard deviation.
By that formula, blur(10px) has an extent of about 19px. Leave at least that much room around the element for the soft edge.
Which blur() values are valid
Lengths in px, rem and em all work, so blur(8px) and blur(1.17rem) are both fine.
blur(0) and an empty blur() change nothing, which makes zero the natural unblurred state. Percentages are invalid, so blur(10%) gives no blur, and the spec doesn’t allow negative numbers either.
MDN’s filter reference adds that an invalid function parameter makes the function return none. A bad value fails quietly and the element renders sharp.
Choosing between filter and backdrop-filter for blur
Reach for filter: blur() when the element itself should go soft. If the element has to stay sharp and only the stuff behind it should blur, that’s backdrop-filter: blur().
| Option | What gets blurred | Needs transparency | Main failure |
|---|---|---|---|
| filter: blur() | The element and all its children | No | Text inside goes soft too |
| backdrop-filter: blur() | Whatever paints behind the element | Yes | Nothing shows on an opaque element |
| Pre-blurred image | The image file itself | No | Blotchy upscaling on 2x screens |
A filter treats the element and all its descendants as one group, so filter: blur(4px) on a card blurs its heading and button too (W3C Filter Effects Module Level 1).
Backdrop-filter needs transparency to show anything. MDN states that the element or its background must be transparent or partially transparent for the effect to appear.
It’s also the property behind the glassmorphism look, a translucent panel over a busy background with sharp text on top.
There’s one spot where backdrop-filter breaks and it catches people out. A child inside a backdrop root only blurs what sits between that root and the child, not the page behind it. MDN lists the triggers as opacity below 1, a filter, a mask, a clip-path, or a mix-blend-mode other than normal.
Engines have not always agreed on that boundary. A March 2019 Chromium intent-to-ship thread recorded that WebKit still wanted backdrop-filter to cover everything behind the element, all the way to the root, while the spec stops at the backdrop root.
Safari 18 shipped the unprefixed property in September 2024 (Apple release notes). Test any faded or filtered parent in Safari anyway.
The third route skips runtime blur. On the Made Mistakes site, images shrunk to about 20px wide and scaled up with background-size: cover showed blotchy artifacts on 2x and higher displays, and a single filter: blur(15px) line fixed it.
How to blur an image, text or background in CSS
Put filter: blur(radius) on the element you want soft. For frosted glass, give the element on top a translucent background plus backdrop-filter: blur(radius).
Blurring an image or text with filter
An image needs one line.
img.soft { filter: blur(6px); }Text blurs the same way, and so does any container. The catch is that a container takes its children with it, so the safe pattern is to blur a separate background layer and keep the content in a sibling.
.hero-bg {
position: absolute;
inset: 0;
background: url(hero.jpg) center / cover;
filter: blur(15px);
}The unblurred state is blur(0), so a hover rule that resets the filter plus transition: filter 0.3s gives a smooth unblur. The W3C draft says blur() interpolates as a length, which is what makes that transition work.
A blurred element still responds to clicks, because filter has no effect on hit-testing (W3C).
Building a frosted glass panel with backdrop-filter
- Place an image or colorful background behind the panel.
- Give the panel a semi-transparent background, for example
rgb(255 255 255 / 30%)(the value MDN uses in its own example). - Add
backdrop-filter: blur(10px), and put-webkit-backdrop-filter: blur(10px)above it for Safari versions before 18. - Wrap the blur in
@supports (backdrop-filter: none) or (-webkit-backdrop-filter: none)and keep a solid, slightly more opaque background outside it as the fallback.
The same recipe fits a sticky navigation bar, where the page scrolls underneath a translucent header. For a modal, put the blur on the overlay, not on the page content.
For the card styling around the blur, see this guide to glassmorphism in CSS.
Browser support for CSS blur, including the Safari prefix
As of October 2026, filter: blur() and backdrop-filter: blur() both work in current Chrome, Firefox and Safari. Only Safari versions before 18 need the -webkit- prefix for the backdrop version.
filter: blur()has been Baseline widely available in every major browser since September 2016 (MDN Web Docs)backdrop-filterreached Baseline newly available in September 2024 (MDN Web Docs)- Chrome supports backdrop-filter from version 76 (web.dev)
- Firefox turned it on by default in version 103, released July 26, 2022, after it sat behind a preference (Firefox release notes)
- Safari dropped the prefix in version 18, released September 16, 2024 (Apple)
Before Safari 18, only the prefixed property worked. WebKit has shipped it that way since 2015, according to the Chromium intent-to-ship thread, so a blur written without the prefix did nothing in Safari.
Declare both lines, prefixed first, and keep the values identical.
Safari 18 also fixed backdrop-filter: blur not rendering on elements added after the page loaded (Apple’s release notes). On older Safari, a modal or toast inserted by script is the case to test.
For unsupported browsers, web.dev recommends falling back to a plain image rather than a polyfill, because a polyfill costs performance.
Treat all of this as routine cross-browser compatibility work. Check the blur in Safari, Chrome and Firefox, on desktop and on a phone.
Does the CSS blur effect slow down a page?
It can. The cost rises with the blur radius and with the size of the blurred area, and how badly it hurts depends on whether the engine runs the blur on the CPU or the GPU.
Why a larger radius costs more
CSS filters and SVG filters both blur with convolution filters, which read a number of input pixels for every output pixel (Chrome for Developers). A bigger image or a bigger radius means more reads, every frame.
| Source | Where the blur ran | Reported result |
|---|---|---|
| Chrome for Developers, Animating a blur (last updated 2017) | GPU shader, because the element was promoted and blurred | About 90ms per frame in the promoted-copies demo |
| WebKit Bugzilla 240865, reported May 2022 | CPU path in WebKitGTK | Over ten seconds per frame at a 60px radius |
| Same report, September 2023 comment | After later WebKitGTK fixes | No slowdown seen in the test case |
Chromium’s own 2019 intent-to-ship for backdrop-filter described it as computationally intensive, like filters in general, while expecting the cost to stay manageable.
The WebKit reporter hit the slowdown on Reddit, where a post marked Spoiler blurs its image at 60px, and called the page unusable in GNOME Web 42.2.
The sources look like they contradict each other. Chrome’s engineers found that promoting the blurred element made animation worse, while a WebKitGTK developer said will-change: transform or translateZ(0) is what makes the element composite on the GPU, where the static blur ran much faster. They aren’t really in conflict, since one source measured an animated blur on a GPU shader and the other a static blur on a CPU path. Neither result transfers to the other engine without a test.
That WebKitGTK workaround had its own bug. In the same 2023 comment, the forced-GPU test page went blank after scrolling.
MDN calls will-change a last resort for existing performance problems and warns that overuse eats memory. Profile first, then add it.
Paint Flashing shows nothing for a promoted blurred element, according to the Chrome post, so the DevTools performance trace is where the busy GPU shows up. Test on a phone too, since desktop GPUs are deceptively powerful.
Animating blur on hover and in transitions
Animating the blur radius is the expensive case. The Chrome team’s write-up calls it very slow.
A blur that changes every frame is a convolution filter re-run on the GPU every frame, and that blows through the 16ms budget that 60fps allows.
The workaround is to pre-compute a few blurred copies at 1px, 2px, 4px and 8px, then cross-fade them with opacity, each stage taking a quarter of the duration. Promote a parent wrapper, not the blurred copies. A blurred element that is not promoted gets rasterized into the nearest parent texture and reused, while a promoted one is re-blurred on every frame.
That write-up was last updated in October 2017 and still treats IE 10 and 11 as a support concern, so read its frame numbers as a pattern, not a benchmark. Its authors also warn that the copied DOM and extra layers can push lower-end phones, and they published a library for the technique in the GoogleChromeLabs ui-element-samples repository.
Honestly, for a plain hover state I’d skip animating blur altogether. There are lighter options, such as the ones in this guide to CSS hover effects.
For multi-step blur changes, CSS keyframes drive the timeline, but the per-frame cost above still applies.
When CSS blur breaks layout or looks wrong
Most blur problems trace back to how the W3C spec defines the filter property.
Edges are the first surprise. The blur spills into the transparent area around the element, so its edges fade, and because filter leaves box geometry alone, neighbors do not move to make room. Clip the spill with overflow: hidden on the parent and scale the blurred element up slightly. CSS-Tricks clips the blurred edges with overflow: hidden in its blurred-border technique.
Fixed children are next. A filter other than none creates a containing block for absolute and fixed positioned descendants, unless the element is the document root (W3C). A position: fixed button inside a blurred wrapper now positions against the wrapper, not the viewport.
Then z-index gets trapped. A filter other than none creates a stacking context the same way opacity does (W3C), and MDN’s stacking context page lists backdrop-filter in the same group. A dropdown inside a blurred header cannot rise above content outside it by raising its own z-index.
The fix for those last two is the same. Apply the blur to a sibling layer so fixed and z-indexed content is not a descendant of the filtered element. MDN adds that will-change on a stacking-context property creates the context up front, so a performance tweak can reshuffle layers too.
Blur also changes nothing outside painting. W3C describes filter as altering how an element paints, so blurred text stays in the document.
Accessibility for blurred text and frosted panels
Text over a blurred background still has to meet WCAG’s contrast minimum, 4.5:1 for normal text and 3:1 for large text, which W3C defines as 18 point or 14 point bold (Success Criterion 1.4.3, Level AA).
Blur softens a background but does not darken it, so the ratio depends on the lightest spot behind the text. W3C lists background images with too little contrast behind text as a named failure (technique F83), and a blurred photo is still a background image.
Check the worst spot with a color contrast tool, then tint the panel until that spot passes.
.panel {
--alpha: 0.5;
background: rgb(255 255 255 / var(--alpha));
backdrop-filter: blur(10px);
}
@media (prefers-reduced-transparency: reduce) {
.panel { --alpha: 0.95; }
}Chrome documents prefers-reduced-transparency for this case, raising a panel’s opacity from 0.5 to 0.95 when the user asks for less transparency. As of October 2026, that documentation lists Chrome 118 and Edge 118, Firefox behind a flag, and Safari as unsupported, and Can I Use data shows the same gap for Firefox and Safari, so treat it as an enhancement.
Keep a solid panel background that passes contrast with no blur at all. Under prefers-reduced-transparency: reduce, raise the panel opacity, and under prefers-reduced-motion: reduce, drop the blur transition.
Both preferences are media queries that read operating system settings. WCAG 2.3.3 (Level AAA) says motion animation triggered by interaction can be disabled unless it is needed for function or information, and technique C39 does that with the reduced-motion query.
The scale and translate that often ride along with a hover blur are the clear cases. Gating the whole transition behind prefers-reduced-motion: no-preference covers the rest without a judgment call.
Chrome DevTools can emulate the reduced transparency preference in the Rendering tab, which makes the fallback easy to test.
CSS Blur Effect Examples To Check Out
CSS Filter Cards
See the Pen
CSS Filter Cards by Steve Meredith (@steveeeie)
on CodePen.
Gradient Blur Text Effect In Pure CSS

Shifting Depth Of Field

Dynamic Inside Blur Pure CSS

Gooey Blurry Text Morph Effect

Pure CSS Motion Blur

CSS3 Blur Filter Animation

Inline CSS Blur for Mozilla

Blurry VHS Image Effect Filter

Blur Buttons

I Love Blur

Black Mirror Style Cracked Glitchy Text Effect

Creating a blurry background image

Loading Animation CSS

Rollover CSS Blur Filter Image Gallery

Pop-Up With Blurred Background Animation

Horror Move Style Blurry Text Coming Into Focus Text Animation

A Blurred Overlay

Blurry Loading Quote Animation Effect

In/Out Of Focus Text Effect

Heat Haze / Heat Shimmer Blurr Effect

Text Blurring Animation

Full Bleed Background images with CSS3

Blurry Lazy Load Images

Recreating Canva’s Blur Effect

Pure CSS Text Blur

Slick Slideshow with Blur Effect by Fabio Ottaviani

Pure CSS Toggle Blur Layer Visibility Using On/Off Buttons

Pure CSS Blurred Video Background Login Box by Lokesh Suthar

CSS Text Transform with Blur by Ambika Castle

Blurry Background

Glitched & Blurred CSS Worms by Fabio Ottaviani

CSS Blur Effect FAQ
Can blur hide sensitive content or spoilers safely?
No. Blur only changes how an element paints (W3C), so the text stays in the document and anyone can read it with view-source or developer tools.
A spoiler that reveals on click is fine. Anything private should stay out of the markup until the user is allowed to see it.
How does CSS blur differ from SVG feGaussianBlur?
The blur itself is the same, and MDN shows blur(1.1px) matching an SVG filter with a stdDeviation of 1.1. SVG accepts up to two stdDeviation values, while blur() takes a single length.
An SVG filter also has a filter region, which extends 10% past each edge by default, and W3C says a very large stdDeviation can get clipped by it.
Which pixel value does each Tailwind backdrop-blur class produce?
Every Tailwind utility maps to a single value. backdrop-blur-md outputs blur(12px), and backdrop-blur-[2px] takes any custom length.
The small sizes moved between versions. backdrop-blur-sm is blur(4px) in v3 and blur(8px) in v4, where blur(4px) is backdrop-blur-xs (Tailwind docs).
How do I fade a blur gradually with a mask?
Put backdrop-filter: blur() on an overlay and add a mask-image gradient to the same element, so the blur weakens where the mask turns transparent. Smashing Magazine’s 2024 gradual-blur tutorial pairs the two this way.
Stack several layers with rising radii and the same mask for a smoother falloff.
Is blur supported on video and iframe elements?

Yes. The W3C draft says filter applies to all elements, so filter: blur() works on a video or an iframe just as it does on an image.
Full-screen areas are the costly case, so test a blurred video background on a phone.
Does the order of filter functions matter when chaining blur with others?
It does. Filter functions run in the order written, and each takes the previous result as its input (W3C).
MDN’s example shows two identical drop shadows ending up in different colors because a hue-rotate() sits between them. Put blur() after a drop-shadow() and it blurs the shadow too.
A Safe Production Setup for the CSS Blur Effect
A production-safe CSS blur effect starts with a solid fallback panel that already passes contrast, then adds the smallest blur radius that still looks right.
Fallback first protects every visitor the blur never reaches, including browsers without backdrop-filter and users who ask for less transparency.
Check contrast on the fallback panel before anything else. After that, keep the radius small and the blurred area smaller, and only touch animation or will-change once the result has survived a phone test.
The trade-off is visual. A tint strong enough to pass contrast over a busy photo makes the panel look less like glass.
This advice was verified on 14 October 2026. It shifts once Safari ships prefers-reduced-transparency, because the reduced-transparency rule then stops being an enhancement and becomes a baseline.
Tune the tint and radius with a CSS glassmorphism generator before running the phone test.
- What is Backend in Web Development? - September 13, 2026
- What is Frontend Development? - September 11, 2026
- How to Make a Button in Figma: Design Best Practices - September 10, 2026








