---
name: glassmorphism
description: Use when you want "Premium, modern, SaaS, portfolio" - Creates translucent panels with blur, light borders, and layered backgrounds.
---

# Glassmorphism

> **Category:** Glass / Depth  -  **Personality:** Premium, modern, SaaS, portfolio
>
> **Best use:** Dashboards, hero cards, app UIs
>
> **Ratings:** Professional 5/5 - Casual 3/5 - Exotic 4/5 - Visual impact 5/5 - Difficulty 3/5 - Performance cost 3/5

## What it is

Glassmorphism makes a surface look like frosted glass: it is semi-transparent, **blurs whatever sits behind it** (`backdrop-filter`), and carries a thin light border plus a soft drop shadow so it reads as a pane floating above the page. It only works when there is something colourful and varied behind it — a gradient, photo, or mesh — so the blur has something to refract. It feels premium and modern, which is why dashboards, hero cards and app UIs lean on it.

## Dependencies / CDN

None for the effect itself (pure CSS). The demo loads display/body fonts — optional:

```html
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:wght@500;700;800&family=DM+Sans:wght@400;500&display=swap" rel="stylesheet">
```

## HTML

Minimal pattern — a glass panel over a colourful backdrop:

```html
<div class="stage">
  <div class="mesh" aria-hidden="true">
    <span class="blob b1"></span><span class="blob b2"></span><span class="blob b3"></span>
  </div>
  <div class="glass card">
    <h3>Revenue this month</h3>
    <strong>$48,920</strong>
    <p>+18.2% vs last month</p>
  </div>
</div>
```

## CSS

```css
/* 1) THE GLASS — the only lines that matter for the effect */
.glass{
  background: linear-gradient(135deg, rgba(255,255,255,.14), rgba(255,255,255,.05));
  -webkit-backdrop-filter: blur(22px) saturate(150%);   /* Safari/iOS need the prefix */
          backdrop-filter: blur(22px) saturate(150%);
  border: 1px solid rgba(255,255,255,.22);              /* light edge catches the light */
  border-radius: 22px;
  box-shadow: 0 20px 60px -16px rgba(0,0,0,.6),          /* float */
              inset 0 1px 0 rgba(255,255,255,.4);        /* top inner highlight */
}

/* 2) A backdrop with variety, so the blur has something to do */
.stage{position:relative; overflow:hidden; border-radius:28px; background:#0a0a12;
  min-height:480px; display:grid; place-items:center; isolation:isolate}
.mesh{position:absolute; inset:0; z-index:0}
.blob{position:absolute; border-radius:50%; filter:blur(58px); opacity:.85}
.b1{width:55%; height:70%; background:#22d3ee; top:-15%; left:-10%}
.b2{width:55%; height:75%; background:#f472b6; bottom:-20%; right:-8%}
.b3{width:48%; height:62%; background:#fbbf24; bottom:-12%; left:28%}

.card{position:relative; z-index:1; padding:24px; color:#fff; min-width:280px}
```

## JavaScript

Not required. (Optional flourish: translate the `.mesh` a few px toward the pointer for parallax — gate it behind `prefers-reduced-motion`.)

```js
var stage=document.querySelector('.stage'), mesh=document.querySelector('.mesh');
if(stage && mesh && !matchMedia('(prefers-reduced-motion: reduce)').matches){
  stage.addEventListener('pointermove',function(e){
    var r=stage.getBoundingClientRect();
    var dx=((e.clientX-r.left)/r.width-.5)*22, dy=((e.clientY-r.top)/r.height-.5)*22;
    mesh.style.transform='translate3d('+dx+'px,'+dy+'px,0)';
  });
}
```

## How it works

- **`backdrop-filter: blur()`** samples and blurs the pixels *behind* the element. This is the whole effect; everything else is dressing.
- **Translucent background** (`rgba` ~0.05–0.15) lets the blurred colour through. Too opaque kills the glass; too transparent kills legibility.
- **`saturate(150%)`** punches up the colours bleeding through so the glass feels alive, not grey.
- **Light 1px border + `inset 0 1px 0` highlight** simulate the lit top edge of a real glass slab; the outer shadow lifts it off the page.

## Customization

- **Frost amount:** `blur(10px)` (light) → `blur(30px)` (heavy milk-glass).
- **Tint:** swap the `background` rgba — cool white for neutral, or a coloured tint like `rgba(110,168,254,.12)`.
- **Edge:** raise border alpha for a crisper rim; raise the inset highlight for more "shine".
- **Depth:** bigger, softer `box-shadow` = floats higher. Stack a second glass element (a chip/badge) overlapping the card to show layering.

## Accessibility & performance

- `backdrop-filter` is GPU-bound; keep the number of simultaneously-blurred panels small and avoid animating the blur radius (animate transform/opacity instead).
- Ensure text contrast holds over the *blurred* background — add a subtle dark tint to the glass if text sits over light areas.
- Provide a fallback: `@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){ .glass{background:rgba(20,22,30,.8)} }`.

## Gotchas

- **Needs the `-webkit-` prefix** for Safari/iOS or it silently does nothing.
- **Nothing behind it = nothing happens.** The element must overlap content/gradient; a glass panel on a flat solid colour looks like a plain translucent box.
- A parent with `overflow:hidden` + `border-radius` should set `isolation:isolate` (or a stacking context) so the blur samples only inside the stage.
- `backdrop-filter` can be defeated by an ancestor `filter`/`transform` creating an unexpected containing block — keep the glass and its backdrop as siblings.
