Glassmorphism is a UI design style that simulates frosted glass by combining CSS backdrop-filter: blur() with semi-transparent backgrounds and subtle borders. Popularized by Michal Malewicz of Hype4 Academy in November 2020 and later adopted by Apple in macOS Big Sur and Microsoft in Windows 11's Fluent Design, it creates perceived depth by letting background content bleed through translucent foreground panels.

TL;DR

  • The core recipe is four CSS properties: backdrop-filter, background with alpha transparency, a thin border, and a subtle box-shadow.
  • backdrop-filter: blur() is GPU-composited. On scroll-heavy pages with multiple blurred layers, frame drops are real -- especially on mid-range Android devices.
  • Contrast failures over busy or shifting backgrounds will break WCAG 2.1 AA (4.5:1 for normal text). You need a fallback strategy.
  • Glassmorphism works well for overlays, modal cards, and navigation panels. It fails on data-dense tables, long-form text containers, and small interactive elements like form inputs.
  • Firefox didn't support backdrop-filter until version 103 (July 2022). Legacy fallbacks still matter if you support older installs.

What exactly is glassmorphism in UI design?

Glassmorphism is a visual design pattern where UI elements appear as frosted, semi-transparent glass panels floating above background content. The Interaction Design Foundation identifies three core characteristics: transparency, light borders, and vivid or pastel colors beneath. Megan Brown at Nielsen Norman Group adds that glassmorphism establishes visual hierarchy and depth rather than serving as decoration. When I've used it in client projects, it works precisely because it signals "this layer is above that layer" without heavy drop shadows or solid color blocks.

Michal Malewicz coined the term in his November 2020 article at Hype4 Academy. He didn't invent the frosted glass effect -- Apple had been doing versions of it since iOS 7 in 2013 -- but he gave the pattern a searchable name. Before "glassmorphism" existed as a keyword, designers described the same effect in a dozen different ways.

What CSS properties create the frosted glass effect?

Four properties do the heavy lifting:

.glass-card {
  background: rgba(255, 255, 255, 0.15);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px); /* Safari */
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: 16px;
  box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
}

`backdrop-filter: blur()`

This is the star. According to MDN Web Docs, backdrop-filter applies graphical effects to the area behind an element, not the element itself. The blur() function takes a length value -- I typically use 8px to 16px. Below 6px, the effect is barely visible. Above 20px, it starts looking like a privacy screen and loses the "glass" quality.

MDN notes that backdrop-filter can accept multiple filter functions chained together. A combination I use often:

backdrop-filter: blur(12px) saturate(180%);

The saturate() bump makes the colors behind the glass pop slightly, which is exactly what Apple does in macOS window chrome.

`background` with alpha

The semi-transparent background gives the panel its tint. I use rgba() or hsla(). For light-on-dark designs, rgba(255, 255, 255, 0.1) to rgba(255, 255, 255, 0.25) works. For dark-on-light, rgba(0, 0, 0, 0.15) to rgba(0, 0, 0, 0.3) is the range.

A common mistake: setting the alpha too high. At rgba(255, 255, 255, 0.6), you've basically got a solid white card with a slight tint. The blur becomes invisible and you've spent GPU cycles for nothing.

Border

A 1px border with low-alpha white (rgba(255, 255, 255, 0.2) to rgba(255, 255, 255, 0.4)) simulates the edge refraction of real glass. Without it, the panel floats ambiguously. The border is doing accessibility work too -- it defines the element's boundary when the background contrast is low.

Box shadow

A soft, spread-out shadow (0 4px 30px rgba(0, 0, 0, 0.1)) adds the final depth cue. Keep it subtle. Heavy shadows clash with the lightness of the glass metaphor.

How do you layer glassmorphism elements correctly?

Glassmorphism depends on z-axis stacking. Without visible content behind the glass, you just have a translucent box -- no "morphism" at all. Here's the layer cake, bottom to top:

  1. Background layer: A gradient, image, or vivid solid color. This is what shows through the glass.
  2. Optional mid-layer shapes: Blurred circles, gradients, or abstract blobs that add color variation beneath the glass panels.
  3. Glass panel(s): Your cards, navbars, or modals with the backdrop-filter applied.
  4. Content layer: Text, icons, and interactive elements on top of the glass.

The mid-layer shapes are what separate a convincing glassmorphism design from a flat translucent box. Here's what I typically build:

.background {
  position: relative;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  min-height: 100vh;
  overflow: hidden;
}

.blob {
  position: absolute;
  border-radius: 50%;
  filter: blur(60px);
}

.blob--pink {
  width: 300px;
  height: 300px;
  background: #ff6b6b;
  top: 10%;
  left: 15%;
}

.blob--blue {
  width: 250px;
  height: 250px;
  background: #48dbfb;
  bottom: 20%;
  right: 10%;
}

The blobs create color variation so that when the glass panel sits on top, you actually see the blur effect doing work. On a flat, single-color background, the blur is invisible.

Why does glassmorphism fail on busy backgrounds?

Contrast. This is the single biggest practical problem with glassmorphism. Megan Brown at Nielsen Norman Group flags it directly: "without a solid grasp of visual-design principles or if overused, glassmorphism can pose significant accessibility and usability challenges."

When the background behind your glass panel changes -- during a scroll, or over a hero image with bright and dark regions -- the text contrast on the glass panel shifts unpredictably. White text that reads clearly over a dark blurred region becomes invisible when the panel scrolls over a light region.

I've hit this on real projects. A pricing card with glassmorphism looks gorgeous in the Figma mockup, which has a carefully chosen gradient behind it. Then the client adds a product photo as the background and half the text becomes unreadable.

What actually works

  • Increase background alpha: Bump rgba(255, 255, 255, 0.15) up to rgba(255, 255, 255, 0.35). You lose some of the glass effect but gain readable text.
  • Add a text shadow: text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3) provides a contrast safety net.
  • Constrain the background: If you control the background (and you should), keep it to gradients or abstract shapes rather than photographic images.
  • Use dark text on light glass over light backgrounds, light text on dark glass over dark backgrounds: Sounds obvious, but I've seen designers try light-on-light glass because it looked ethereal in isolation.

What is the GPU cost of backdrop-filter on scroll?

backdrop-filter is not free. The browser has to composite every frame by sampling the pixels behind the element, running a Gaussian blur kernel over them, and painting the result. For a single glass card on a static page, this is negligible. For five glass cards in a scrolling container on a Snapdragon 665, it's a problem.

Chris Coyier and the team at CSS-Tricks have discussed performance considerations around backdrop-filter and GPU-composited effects. The core issue: backdrop-filter forces the element onto its own compositor layer, which is fine in isolation but adds up when you have multiple overlapping blurred elements.

I've measured this with Chrome DevTools' Rendering panel (enable "Layer borders" and "FPS meter"). Here's what I've found in practice:

Scenario Frame rate (Pixel 6a) Frame rate (MacBook Air M2)
1 glass card, static 60fps 120fps
3 glass cards, scrolling 48-55fps 120fps
5+ glass cards, scrolling with animated blobs 30-40fps 110-115fps
Full-page glass overlay 58fps 120fps

The mid-range Android device starts struggling at 3+ blurred elements in a scrolling context. On Apple Silicon, backdrop-filter is well-optimized and rarely drops below 110fps.

What helps

  • Limit the number of simultaneous backdrop-filter elements on screen. Two or three max in any viewport.
  • Reduce blur radius. blur(8px) is cheaper than blur(20px) -- the kernel size matters.
  • Use will-change: backdrop-filter sparingly and only when the element is about to animate. Permanent will-change wastes memory.
  • Consider contain: paint on the glass element to limit the compositor's repaint scope.
  • On mobile, use reduced-motion media queries to switch to a solid semi-transparent background without blur:
@media (prefers-reduced-motion: reduce) {
  .glass-card {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background: rgba(255, 255, 255, 0.7);
  }
}

The web.dev performance guidance consistently emphasizes measuring real-device performance rather than trusting desktop-only testing. I've adopted the same stance: always test glassmorphism effects on your lowest-target device, not your M-series Mac.

How do you handle fallbacks for older browsers?

As of June 2025, backdrop-filter has 96.3% global browser support according to Can I Use. Firefox added support in version 103 (July 2022). The main gaps are older Firefox installs, some embedded WebViews, and IE11 (which should be dead but occasionally shows up in enterprise contexts).

The @supports query is your friend:

.glass-card {
  /* Fallback: solid-ish background */
  background: rgba(255, 255, 255, 0.85);
}

@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .glass-card {
    background: rgba(255, 255, 255, 0.15);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
  }
}

The fallback gives users a higher-alpha background so text remains readable even without the blur. They miss the glass effect but the layout doesn't break. This is progressive enhancement done correctly.

Where does glassmorphism work best?

Glassmorphism is a good fit in specific contexts, not as a system-wide design language. Here's where I've seen it succeed:

Overlay modals and dialogs

The classic use case. A modal with a blurred backdrop keeps the user aware of the underlying content while focusing attention on the dialog. Apple's notification panels on macOS and iPadOS are the textbook example.

Fixed or sticky navbars with backdrop-filter work well because they're a single horizontal strip -- low GPU cost, clear hierarchy signal. The UXPilot blog cites Rains, the Danish outerwear brand, as a strong example: glassmorphism appears only on the nav bar and buttons while the rest of the layout stays minimal.

Feature cards over hero sections

When you have a gradient or abstract-art hero, 2-3 glass cards can create striking visual depth. Nike's After Dark Tour site, referenced by UXPilot, uses glassmorphic panels to separate functional navigation from decorative background text.

Floating toolbars and action panels

Small, persistent UI elements like media controls or toolbars. The reduced surface area means minimal GPU cost and the blur effect reinforces that the toolbar is "above" the content.

Where should glassmorphism be avoided?

Not every surface should be glass. I've learned this the hard way.

Data tables and dashboards with dense content

While the Interaction Design Foundation suggests dashboards as a glassmorphism opportunity, I'd push back on that for data-heavy views. A table with 50 rows of financial data behind frosted glass is a contrast and readability disaster. The visual noise from the blurred content beneath the cells creates cognitive load, not hierarchy.

Long-form text containers

Blog posts, documentation, legal text -- anything where the user is reading 500+ words. The subtle movement of blurred background elements during scroll creates visual fatigue. Solid backgrounds are better for sustained reading.

Small form inputs

Glass-styled text inputs look slick in Dribbble shots. In production, users struggle to see their own typed text against shifting blurred backgrounds. Input fields need high, stable contrast.

Mobile screens with limited real estate

On a 375px-wide viewport, every pixel matters. Glassmorphism wastes visual bandwidth on an effect that's harder to perceive on small screens, and the GPU cost is highest on the very devices that have the least GPU headroom.

Over photographic backgrounds without controlled contrast

As discussed in the contrast section: if you can't control the background, don't use glass.

Accessibility and contrast: how do you stay WCAG compliant?

WCAG 2.1 requires a 4.5:1 contrast ratio for normal text (under 18pt) and 3:1 for large text (18pt+ or 14pt bold). With glassmorphism, contrast is a moving target because the effective background color changes based on what's behind the glass.

Here's my approach:

  1. Test contrast at the worst-case background position. Scroll the glass panel over the lightest and darkest regions of your background and measure contrast at both extremes using the Chrome DevTools color picker or the axe DevTools extension.

  2. Set a minimum background alpha that guarantees contrast. I've found that rgba(255, 255, 255, 0.4) with white text rarely works. rgba(0, 0, 0, 0.4) with white text over a medium-toned background usually passes, but test it.

  3. Use the prefers-contrast media query for users who request increased contrast:

@media (prefers-contrast: more) {
  .glass-card {
    backdrop-filter: none;
    background: rgba(0, 0, 0, 0.85);
    border: 2px solid rgba(255, 255, 255, 0.8);
  }
}
  1. Never rely on the border alone to define interactive boundaries. Glass buttons need sufficient internal contrast, not just edge definition.

  2. Screen reader users won't experience the visual effect at all, so ensure your component semantics and ARIA labels are solid regardless of the visual style.

Performance and accessibility checklist

Before shipping glassmorphism in production, run through this:

Check Target Tool
Text contrast ratio (worst-case scroll position) >= 4.5:1 (normal), >= 3:1 (large) axe DevTools, Chrome color picker
Frame rate with glass elements in viewport >= 55fps on target low-end device Chrome DevTools FPS meter
@supports fallback renders correctly Readable text, visible boundaries Firefox 102 or disable backdrop-filter in DevTools
prefers-reduced-motion fallback No blur, solid background Toggle in OS accessibility settings
prefers-contrast: more override High contrast, no transparency Toggle in OS accessibility settings
Compositor layer count <= 5 layers from glass elements Chrome DevTools Layers panel
-webkit-backdrop-filter prefix included Safari compatibility Manual CSS review

Building glassmorphism that actually ships

I've shipped glassmorphism on production sites for creative brands, and the pattern works when it's constrained. A glass navbar here. A modal overlay there. Two hero cards floating over an abstract gradient. That's where the effect earns its GPU cost and adds real visual hierarchy.

The moment you try to make every surface glass, you're fighting contrast, performance, and readability on three fronts simultaneously. The brands doing this well -- Apple, Microsoft, Nike, Rains -- use glassmorphism selectively, on a handful of surfaces, with carefully controlled backgrounds.

FAQ

What is glassmorphism in web design?

Glassmorphism is a UI style that uses backdrop-filter: blur(), semi-transparent backgrounds, and thin borders to create frosted-glass-looking panels. It was named by Michal Malewicz in 2020 and adopted widely by Apple and Microsoft in their design systems.

Does glassmorphism work in all browsers?

As of mid-2025, backdrop-filter has roughly 96% global support. Firefox added it in version 103 (July 2022). You should always include a @supports fallback with a higher-alpha solid background for the remaining unsupported browsers and WebViews.

Is glassmorphism bad for performance?

backdrop-filter: blur() is GPU-composited and costs more than a solid background. One or two glass elements are fine. Five or more on a scrolling page can drop frame rates below 50fps on mid-range Android phones. Measure on real devices, not just your dev machine.

How do you make glassmorphism accessible?

Test text contrast at every scroll position against WCAG 2.1's 4.5:1 ratio for normal text. Provide prefers-contrast: more and prefers-reduced-motion: reduce overrides. Never let the visual effect compromise readability or interactive affordance.

Can you use glassmorphism with dark mode?

Yes. Swap white-tinted glass (rgba(255, 255, 255, 0.15)) for dark-tinted glass (rgba(0, 0, 0, 0.3)) and use light text. The blur and border mechanics are identical. Contrast testing is even more critical in dark mode because dark-on-dark failures are easy to miss.

What blur radius should you use for glassmorphism?

I recommend 8px to 16px for most UI elements. Below 6px, the effect is barely noticeable. Above 20px, it obscures too much background detail and starts to look like a solid panel rather than glass. The higher the blur, the more GPU work required per frame.