Glassmorphism looks effortless in design mockups, then falls apart in the browser: text becomes unreadable over busy photos, some Apple devices show a plain transparent box, and scrolling stutters on phones. This guide explains how glassmorphism CSS actually works, how to ship it safely with prefixes and fallbacks, and how to keep frosted glass panels both readable and fast.

What Makes the Frosted Glass Effect Work

A convincing frosted glass panel has four ingredients, and missing any one of them breaks the illusion:

  1. A semi-transparent fill, usually white at low opacity on light designs or a dark tint on dark designs.
  2. A background blur applied to whatever sits behind the panel, using backdrop-filter.
  3. A subtle edge, typically a one-pixel translucent white border that mimics light catching the edge of the glass.
  4. Something worth blurring. Glass over a flat white page just looks like a grey box. The effect needs color, shapes or imagery behind it.

That last point is the one most often missed. Glassmorphism is a relationship between a panel and its backdrop, so design the background first: soft gradient blobs, a photo, or overlapping colored shapes. The multi-color gradient generator is a quick way to build a three-stop backdrop for testing, and our post on creating better gradient backgrounds covers how to keep that backdrop from looking muddy.

The Core Glassmorphism CSS

.glass {
  background: rgb(255 255 255 / 0.18);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
  backdrop-filter: blur(16px) saturate(160%);
  border: 1px solid rgb(255 255 255 / 0.35);
  border-radius: 20px;
  box-shadow: 0 8px 32px rgb(15 23 42 / 0.18);
}

Here is what each line contributes:

  • background sets the tint. Its alpha controls how much of the backdrop shows through; roughly 0.1 to 0.3 is typical for white glass.
  • backdrop-filter: blur() blurs the content behind the element, not the element itself. That is the key difference from filter: blur(), which would blur the panel and its text.
  • saturate() is optional but helpful. Blurring averages neighboring colors and dulls them, and a mild saturation boost keeps the backdrop vivid.
  • The translucent border and soft box-shadow separate the panel from its surroundings, so its edges stay visible even where the backdrop is pale.

The fill must stay at least partly transparent. If it is fully opaque, there is nothing to see through and the blur has no visible effect. The glassmorphism CSS generator handles this balance for you: pick a glass tint and a background color, move the intensity slider to control transparency and blur together, and copy CSS that already includes the rgba background, the prefixed and unprefixed backdrop-filter, a subtle border, a shadow and a radius.

Backdrop-Filter Blur Support and the -webkit- Prefix

All current major browsers support backdrop-filter, but Safari required the -webkit-backdrop-filter prefix until relatively recent versions, and plenty of older iPhones and Macs are still in use. Declare the prefixed property first and the standard one second, with identical values. A missing prefix is the most common reason a glass card works in Chrome but looks like a bare transparent box on some Apple devices.

Two side effects are worth knowing. Any backdrop-filter value other than none creates a new stacking context, so a dropdown inside a glass header may end up trapped behind other content until you adjust z-index on the header itself. It also makes the element the containing block for position: fixed descendants, which means a fixed modal nested inside a glass navigation bar will be positioned relative to the bar instead of the viewport. Render modals outside glass containers to avoid both problems.

Fallbacks With @supports

When a browser cannot apply the blur, a panel designed for 0.18 opacity becomes a nearly invisible film over a busy background, and the text on it fails contrast. The safe pattern is to make the default style readable without any blur, then switch to real glass only where it is supported:

.glass {
  /* fallback: mostly opaque, readable everywhere */
  background: rgb(255 255 255 / 0.88);
  border: 1px solid rgb(255 255 255 / 0.35);
  border-radius: 20px;
}

@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .glass {
    background: rgb(255 255 255 / 0.18);
    -webkit-backdrop-filter: blur(16px) saturate(160%);
    backdrop-filter: blur(16px) saturate(160%);
  }
}

The query tests both the prefixed and unprefixed property, so older Safari versions still receive the glass styles while any browser without support keeps the opaque, readable version.

Keeping Text Readable on Busy Backgrounds

Contrast is the hardest part of glassmorphism because the background behind the text is not one color. As the page scrolls or the hero image changes, the same white text may sit over pale sky in one spot and dark foliage in another. Techniques that help:

  • Increase the blur before the opacity. A stronger blur flattens detail into soft color fields, making the effective background far more uniform while keeping the glass look.
  • Make text-heavy panels more opaque. Decorative glass can be very transparent; a panel holding paragraphs or form fields should be noticeably more solid.
  • Commit to one direction. Use dark text on light glass or light text on dark glass. Mid-tone glass with mid-tone text fails almost everywhere.
  • Favor heavier weights and larger sizes. Thin, small text is the first to become illegible.
  • Calm the backdrop. Soft gradients behave far better than detailed photographs. If you must use a photo, darken or lighten it with an overlay first.

How to test contrast on glass

Because the background varies, test the worst case rather than the average. Take a screenshot of the panel in place, load it into the image color picker, and click the lightest and darkest points directly behind your text to read their exact pixel colors. Then check each one against your text color in the color contrast checker. If either fails WCAG AA (4.5:1 for normal text), raise the tint opacity or the blur until both pass. Our guide to choosing readable text colors for the web explains the thresholds in more detail.

Glassmorphism Performance on Mobile

Backdrop blur is one of the more expensive visual effects in CSS. The browser must read the pixels behind the element, blur them and composite the result, and it repeats that work whenever something behind the panel changes, such as during scrolling or when content animates underneath. The cost grows with the blur radius and with the blurred area.

  • Keep glass panels small. A glass card or navigation bar is reasonable; a full-screen glass overlay costs far more.
  • Avoid glass on glass. Each layer adds its own blur pass, and nested panels rarely look better anyway.
  • Do not animate the blur radius. Transitioning backdrop-filter recalculates the effect every frame. Fade the panel with opacity or move it with transform instead.
  • Reduce blur on small screens if testing on mid-range phones shows dropped frames. Place this rule after the @supports block:
@media (max-width: 640px) {
  .glass {
    -webkit-backdrop-filter: blur(10px) saturate(140%);
    backdrop-filter: blur(10px) saturate(140%);
  }
}

Some browsers also support the prefers-reduced-transparency media query, which lets people who find translucent interfaces hard to read ask for solid surfaces. Support is still limited, so treat it as an enhancement on top of a readable default:

@media (prefers-reduced-transparency: reduce) {
  .glass {
    background: rgb(255 255 255 / 0.95);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

Dark Glass and Tinted Glass

The same recipe works on dark interfaces with the fill reversed: a dark translucent tint such as rgb(15 23 42 / 0.45), a faint white border at around 0.08 to 0.12 alpha, and light text. Dark glass is often easier to keep readable because dark tints hide backdrop detail well. Tinted glass, using a brand hue instead of white or black, works best when the tint is close to the backdrop's dominant color; a clashing tint fights the colors showing through. If you want exact alpha values in HEX form, the HEX opacity calculator converts any opacity percentage into an 8-digit HEX code alongside rgba() and hsla(). For depth, pair glass panels with soft, low-opacity shadows; our CSS box shadow guide explains how to layer them.

Conclusion

Good glassmorphism is restrained: a colorful but calm backdrop, a semi-transparent tint, a moderate blur declared with and without the -webkit- prefix, a fine border, and a readable fallback for when the blur is unavailable. Test the worst-case contrast, keep panels small on mobile, and the frosted glass effect will hold up outside the mockup. Generate a starting point with the glassmorphism generator, then tune opacity and blur against your real content.