GlassmorphismFree

Frosted Panel

A still frosted panel inside a 340 × 230 px dark frame: the glass (backdrop-filter: blur(24px)) fills the frame 30 px from the edges while three gradient blobs drift and rotate behind it continuously, over 7, 8 and 10 s — the backdrop moves, never the text. Pure CSS.

CSSAnimationBlur

Updated

Frosted Panel

Blobs move behind the frosted glass

Hover or click the scene to interact

This effect is free — the Glassmorphism category contains 47 effects total, including 6 free. Effect.Labs has 840 vanilla effects. Explore the category →

Usage examples

Le Lavoir physiotherapyRunning 10 min late · 10:42

Next patient: Mr B.

Room 2, end of the corridor

While you wait: 5 minutes on the exercise bike, resistance 2, without forcing.

① Timetable panel in a waiting room — wall screen of a physiotherapy practice

WhenA screen on the waiting-room wall: current delay, next patient called, warm-up instructions, over a slowly moving colored backdrop.
WhyThe slow motion behind the glass occupies the eye without shaking the text, which stays still and readable from across the room; the closed frame drops straight into a wall screen. The three different durations (7, 8, 10 s) only realign the blobs every 280 s: a patient waiting ten minutes rarely sees the same backdrop twice.
SettingsFrame enlarged to 440 × 262 px inside a TV, #06141a background; blobs of 230, 200 and 150 px recolored in calm tones (teal, green, blue); 30 px inset kept; 24 px title for reading at a distance, instruction at 86% white; the patient shown by initial, never by name; a single dot lit.
LiveShowsPodcastsVolunteer
ON AIR

Hands in the soil

with Josiane and Karim · 10 am – 11 am · gardening in the bocage

Coming up 11:00The district news, local edition 11:15Market day: who sells what this Saturday

② "On air" box of a community radio — live listening page

WhenThe listener opens the web player: the frosted panel gives the show and the host while it is on air.
WhyThe blobs drifting behind the glass say the station is live without a costly audio visualizer — no Web Audio, no canvas, nothing running in JavaScript during an hour of listening; their colors take on the station's brand.
SettingsFrame as a 496 × 206 px box on a light page, #1a0f0a background; yellow → orange, red → raspberry and orange → yellow blobs; panel at inset: 22px and in a row (58 px white play button on the left, show title, time slot); dots in the three brand colors; "Coming up" schedule under the frame.
Level 27Score 18,450

Pause

Level 27 · The Cliffs · 14 moves left

★★☆

③ Pause screen of a puzzle game on a tablet

WhenThe player pauses: the level keeps moving, blurred, behind a panel offering resume, restart or quit.
WhyThe frosted panel keeps the level present in the background, so the player doesn't lose the thread; only the backdrop moves, the buttons stay steady under the finger. The overflow: hidden frame lines up with the game screen without blobs spilling onto the interface.
Settings496 × 316 px frame in the tablet, a board of 40 colored pieces placed behind the blobs; panel at inset: 30px 70px, 8% white; three stacked buttons (Resume in solid yellow, the other two in glass); dots hidden, replaced by the level's stars.

How it works

One frame, three blobs, one panel. The frame .frosted-panel-scene is 340 × 230 px, #080812 background, 16 px corners and overflow: hidden: it carries its own backdrop, the page around keeps its color, and blobs that overflow are cut cleanly at the edge. The three .frosted-blob blobs are 135° gradient circles blurred by filter: blur(30px): 160 px violet → indigo starting from the top-left corner (−30, −20 px), 140 px cyan → blue from the bottom-right corner, 100 px pink → raspberry placed in the middle (top: 50%; left: 60%). The panel .frosted-panel-element is position: absolute; inset: 30px — 280 × 170 px measured in the original frame —, 5% white, backdrop-filter: blur(24px) and -webkit-backdrop-filter, 10% white border, 12 px corners, content centered in a column (19.2 px bold title, 12 px text at 50% white, three 8 px dots in the blob colors).

All the motion is in the backdrop. blobDrift1 (8 s) walks the violet blob through four steps — (40, 20), (20, 60), (−10, 30) px — while turning it three quarters of a turn (0 → 270°), then back in the last quarter: since the blob is a gradient, its rotation turns the direction of the color under the glass. blobDrift2 (10 s) brings the cyan blob up to (−50, −40) px, rotating the other way; blobDrift3 (7 s) moves the pink blob by (−40, −30) px while growing it 30%. Three durations that do not divide one another (7, 8, 10 s): the pattern only repeats after 280 s, so the backdrop never seems to loop. Measured in Chromium and Firefox: three running animations, panel 30 px from each edge. No hover, no JavaScript, no site variable.

Accessibility

  • No prefers-reduced-motion in the code: under emulation the three blobs keep drifting and rotating. The text itself never moves. For a waiting screen watched for a long time, add @media (prefers-reduced-motion: reduce) { .frosted-blob { animation: none } }: the panel keeps its colors, frozen.
  • Varying contrast: the bold 19.2 px white title measures 15.6:1. The 12 px text at 50% white depends on which blob is passing underneath: measured at 5.0:1 over a dark area and 2.9:1 with the violet blob behind it — below the 4.5:1 threshold. Raise it to 80–85% white (rgba(255,255,255,.85)), as in the three examples, so it holds wherever the blobs are.
  • Screen readers: an h3 title and a paragraph, read normally; blobs and dots are empty elements, ignored. The dots look like a page indicator but are wired to nothing: don't give them meaning ("3 messages") without saying it in text too, or hide them with aria-hidden="true".
  • Reduced transparency: nothing handles prefers-reduced-transparency. One rule is enough: @media (prefers-reduced-transparency: reduce) { .frosted-panel-element { background: rgba(20,20,40,.9); backdrop-filter: none } }.

Browser compatibility

CSS only: backdrop-filter (with -webkit-backdrop-filter), filter: blur(), gradients, @keyframes on transform (translate, rotate, scale), inset. Zero JavaScript, zero dependency. Backdrop blur: Chrome 76+, Edge 79+, Firefox 103+, Safari 9+ prefixed (unprefixed since 18). Measured in Chromium 151: blur painted, three running animations. In Firefox 153 and WebKit 26.5 (Playwright), the computed value is blur(24px) and CSS.supports returns true, but their automated screenshots do not paint backdrop blur, even on a minimal test: the glass rendering was only seen in Chromium. Animations on transform run on the compositor: no layout recalculation.

Chrome 76+✓ Full
Firefox 103+✓ Full (blur not verifiable in automated screenshots)
Safari 9+✓ Full (-webkit- prefix included)
Edge 79+✓ Full
Mobile iOS 9+✓ Full
Android Chrome 76+✓ Full

Without backdrop-filter, the panel stays a 5% white veil over blobs that are already blurred (filter: blur(30px)): the moving color stays visible, only the frosting disappears, and the text still sits on the frame's dark backdrop. inset needs Chrome 87, Firefox 66 and Safari 14.1; before that, replace it with top/right/bottom/left: 30px.

The code

Copy the three blocks into your page. No dependencies.

HTML
<div class="frosted-panel-scene">
    <div class="frosted-blob frosted-blob--1"></div>
    <div class="frosted-blob frosted-blob--2"></div>
    <div class="frosted-blob frosted-blob--3"></div>
    <div class="frosted-panel-element">
      <h3>Frosted Panel</h3>
      <p>Blobs move behind the frosted glass</p>
      <div class="frosted-dots">
        <span class="frosted-dot"></span>
        <span class="frosted-dot"></span>
        <span class="frosted-dot"></span>
      </div>
    </div>
  </div>
CSS
.frosted-panel-scene {
  width: 340px;
  height: 230px;
  position: relative;
  overflow: hidden;
  border-radius: 16px;
  background: #080812;
}

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

.frosted-blob--1 {
  width: 160px;
  height: 160px;
  background: linear-gradient(135deg, #a855f7, #6366f1);
  top: -30px;
  left: -20px;
  animation: blobDrift1 8s ease-in-out infinite;
}

.frosted-blob--2 {
  width: 140px;
  height: 140px;
  background: linear-gradient(135deg, #06b6d4, #3b82f6);
  bottom: -40px;
  right: -20px;
  animation: blobDrift2 10s ease-in-out infinite;
}

.frosted-blob--3 {
  width: 100px;
  height: 100px;
  background: linear-gradient(135deg, #ec4899, #f43f5e);
  top: 50%;
  left: 60%;
  animation: blobDrift3 7s ease-in-out infinite;
}

.frosted-panel-element {
  position: absolute;
  inset: 30px;
  background: rgba(255, 255, 255, 0.05);
  backdrop-filter: blur(24px);
  -webkit-backdrop-filter: blur(24px);
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  z-index: 1;
}

.frosted-panel-element h3 {
  font-size: 1.2rem;
  font-weight: 700;
  color: #fff;
  margin: 0;
}

.frosted-panel-element p {
  font-size: 0.75rem;
  color: rgba(255, 255, 255, 0.5);
  margin: 0;
  text-align: center;
  padding: 0 20px;
}

.frosted-panel-element .frosted-dots {
  display: flex;
  gap: 6px;
  margin-top: 4px;
}

.frosted-panel-element .frosted-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.3);
}

.frosted-panel-element .frosted-dot:nth-child(1) {
  background: #a855f7;
}

.frosted-panel-element .frosted-dot:nth-child(2) {
  background: #06b6d4;
}

.frosted-panel-element .frosted-dot:nth-child(3) {
  background: #ec4899;
}

@keyframes blobDrift1 {

  0%,
  100% {
    transform: translate(0, 0) rotate(0deg);
  }

  25% {
    transform: translate(40px, 20px) rotate(90deg);
  }

  50% {
    transform: translate(20px, 60px) rotate(180deg);
  }

  75% {
    transform: translate(-10px, 30px) rotate(270deg);
  }
}

@keyframes blobDrift2 {

  0%,
  100% {
    transform: translate(0, 0) rotate(0deg);
  }

  25% {
    transform: translate(-30px, -20px) rotate(-90deg);
  }

  50% {
    transform: translate(-50px, -40px) rotate(-180deg);
  }

  75% {
    transform: translate(-20px, -10px) rotate(-270deg);
  }
}

@keyframes blobDrift3 {

  0%,
  100% {
    transform: translate(0, 0) scale(1);
  }

  50% {
    transform: translate(-40px, -30px) scale(1.3);
  }
}
JavaScript (fx-0302)

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
Frame size (CSS — .frosted-panel-scene { width: 340px; height: 230px }) 340 × 230 px, 16 px corners The panel follows on its own thanks to inset: 30px. For a large screen, enlarge the blobs too (200–240 px): at their original size they only cover one corner of the glass.
Panel inset (CSS — .frosted-panel-element { inset: 30px }) 30 px on each side The unblurred strip around the glass shows the blobs sharp and makes the frosting readable by contrast. inset: 30px 70px gives a narrower panel (game pause); inset: 0 removes the strip and the effect becomes a plain blurred backdrop.
Glass blur (CSS — backdrop-filter: blur(24px) and -webkit-backdrop-filter) 24 px The blobs are already blurred at 30 px: below 12 px the glass no longer stands out from the strip around it. 24–32 px for even sheets of color under the text.
Blob colors (CSS — .frosted-blob--1 to --3, linear-gradient(135deg, …)) violet → indigo, cyan → blue, pink → raspberry Keep a two-tone gradient per blob: it is what makes the rotation visible. Match the dots (.frosted-dot:nth-child(n)) to the same colors.
Drift speed (CSS — blobDrift1 8s, blobDrift2 10s, blobDrift3 7s) 8, 10 and 7 s Multiply all three by the same factor to slow down (×2: 16, 20, 14 s) while keeping durations that don't divide one another. Equal durations would make the blobs move as a block.
Frame background (CSS — .frosted-panel-scene { background: #080812 }) #080812 A color close to the blobs' dominant hue (#06141a for greens, #1a0f0a for oranges) gives a richer backdrop than black. An image works too: the blobs then pass over it.

FAQ

How is it different from Glass Card (fx-0301)?

Glass Card is a card floating above its backdrop, with a drop shadow, a diagonal highlight and a 4 px lift on hover: you interact with it. Frosted Panel reacts to nothing: it fills its frame 30 px from the edges and the backdrop is what lives, three blobs drifting and rotating over 7, 8 and 10 s. Pick Frosted Panel when the screen is watched rather than touched (wall screen, live box, pause) and the motion must say "this is active" without moving the text.

Is continuous motion expensive to display?

Not much. The three animations only touch transform (translate, rotate, scale), which the browser hands to the compositor without recalculating layout. The real cost is the blur: the panel redoes its 24 px backdrop-filter every frame, over 280 × 170 px in the original frame. On a wall screen running all day, keep a reasonable frame size and add the prefers-reduced-motion rule; on a low-end TV, a 16 px blur lightens it further.

Can I use an image instead of the blobs?

Yes: set the image as the frame's background (.frosted-panel-scene { background: url(...) center/cover }) and keep or remove the blobs. With the blobs, they pass over the image and tint the glass; without them, the panel becomes still on a still backdrop — then Glass Card (fx-0301), minus the hover, is what you need. The 30 px inset leaves the image sharp around the glass: that sharp/blurred contrast is what makes the frosting read.