GlassmorphismFree

Glass Card

A 260 × 160 px glass card in pure CSS: a single backdrop-filter: blur(20px) layer, a diagonal highlight in ::before, three colored orbs floating behind it on a 6 s loop, and a 4 px lift on hover — the dark backdrop is carried by the scene itself, readable on a white page.

CSSBackdropHover

Updated

Glass Card

Hover for the effect

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

‹ My hikesSaved offline
Today's route · loop

Trois Cornes pass

4 h 30walking time
+820 mascent
11.4 kmdistance

Water point: Chalets spring at km 6.2, flowing until October.

① Trail card laid over the photo of the pass — mountain hiking app

WhenA hiker opens today's route: the panoramic photo of the pass fills the screen, the glass card gives walking time, ascent and water point.
WhyThe blur keeps the colors of the landscape — the blue of the ridges, the gold of dawn — without scrambling the numbers; one card, no script, nothing to weigh down an app often opened with poor signal. The three orbs become patches of light (sun, sky, alpenglow) drifting slowly behind the glass like morning light.
Settings.glass-card-scene stretched over the whole screen (inset: 0, square corners) with the painted panorama as background instead of #080812; 300 px card bottom left, free height, white raised to 10% for readability over the sky; orbs recolored gold #fbbf24, sky blue and pink; three figure tiles and the water point in 12 px at 88% white.
Room 12 · Harbours and shoresAudio guide · EN
No. 12.4 · scanned

Honfleur, the harbour at daybreak

Berthe Lemoine (1841-1913)

Oil on canvas, 1879 · 65 × 81 cm

Track 24 · 2 min 40 s

② Label of a work laid over the painting — fine-arts museum audio guide

WhenThe visitor scans the room number: the painting fills the phone screen, the glass label gives title, artist, date and audio track.
WhyThe glass lets the colors of the work show through behind the text instead of hiding them under an opaque strip; the slight lift on touch signals that the label opens. The diagonal highlight of ::before recalls the glass of a frame.
SettingsPainting drawn in CSS over the whole scene; 288 px label bottom right, dark tint rgba(20,22,48,.18) instead of 7% white because the painted sky is light; 18 px serif title; orange, lilac and blue orbs taken from the painting's palette; an audio row (play button and progress bar) added under the reference.
Domaine des Grès Hauts The estateOur winesVisitsShop
Grown on the terraces, picked by handFour hectares of old vines facing south-west.
Red · old vines

Les Grès rouges 2022

GrapesSyrah 80%, Grenache 20%
VintageHot summer, picked on 2 September
PairingSlow-cooked lamb, aged goat's cheese
75 cl bottle€19

③ Wine label over the photo of the vines — wine estate website

WhenA wine's page: the photo of the rows at sunset as background, the glass card sums up grapes, vintage and food pairing.
WhyThe estate sells a landscape as much as a wine: the translucent card keeps it visible, and the colored orbs take on the color of the wine — garnet, purple, ruby — glowing behind the label. The setting sun placed behind the card becomes a soft patch of light in the glass.
SettingsBackground: vine rows in perspective (repeating-conic-gradient), hills and evening sky; 264 px card on the right, tint rgba(40,10,24,.16); orbs in #9f1239, #7e22ce and #e11d48; three labeled lines (grapes, vintage, pairing) split by a 14% white rule, price at the bottom.

How it works

Two levels in one container. The container .glass-card-scene (320 × 220 px, background: #080812, border-radius: 20px, overflow: hidden) carries the backdrop: three .glass-card-orb orbs of 120, 100 and 80 px — violet #8b5cf6 top left, cyan #06b6d4 bottom right, pink #ec4899 in the middle — blurred by filter: blur(40px) and animated by glassOrbFloat (6 s, ease-in-out, looping, offset by 0, −2 and −4 s): at 33% they drift 15 px right and 10 px up while growing 10%, at 66% 10 px left and 15 px down while shrinking 10%. On top, the card .glass-card-element (260 × 160 px, z-index: 1, 16 px corners) is white at 7% opacity with backdrop-filter: blur(20px) and its -webkit- prefix, a 12% white border and a 0 8px 32px black shadow at 40%. That backdrop blur is what makes the glass: it spreads the already-blurred orbs into sheets of color under the text.

The ::before pseudo-element adds the highlight: a 135° gradient from 12% white to transparent at mid-card, with pointer-events: none so it never blocks the hover. On hover the card rises 4 px (translateY(-4px), measured in Chromium and Firefox) and its shadow turns into a violet 0 12px 40px glow at 30%, over 0.3 s. Title in 17.6 px bold white, subtitle in 12.8 px at 60% white. No JavaScript, no dependency, no site variable.

Two choices in the code depend on the page you will paste it into. The dark #080812 backdrop is carried by .glass-card-scene itself, with rounded corners and overflow: hidden to keep the orb halos inside the frame: without that backdrop, on a white page, the white title would drop to 1.9:1 and 1.7:1 contrast at the two corners of the card (measured), against 5.9:1 at the same points with it — and the surrounding page keeps its own color. The pink orb is placed with top and left: calc(50% - 40px) rather than transform: translate(-50%, -50%): the animation rewrites transform, so centering by translation would be overwritten — its corner, not its center, would land in the middle, 40 px too low and too far right. Measured, its center only moves away from the middle by the animation's own translation.

Accessibility

  • No prefers-reduced-motion in the code: under emulation the three orbs keep floating. The motion is slow (6 s, a few pixels) and behind a blur, but it is a looping animation with no stop button: add @media (prefers-reduced-motion: reduce) { .glass-card-orb { animation: none } } — the orbs stay put and the glass keeps its colors.
  • Contrast measured on the original backdrop: bold 17.6 px white title at 8.9:1, 12.8 px subtitle at 60% white at 4.3:1 — just under the 4.5:1 threshold for body text. Raise it to 75% white (rgba(255,255,255,.75)) to pass. On a light photo, 7% white is no longer enough: darken the card tint (background: rgba(20,22,48,.2), as in the museum scene) rather than increasing the blur.
  • Keyboard and screen readers: the card is a div with cursor: pointer but no link and no role — nothing happens on click and Tab never stops on it. If it leads somewhere, make it an <a> or put a link in the title, and repeat the hover style under :focus-visible. If it is only an information block, remove cursor: pointer. The orbs are empty divs, ignored by speech output.
  • Transparency preferences: nothing handles prefers-reduced-transparency or high-contrast mode. One rule is enough: @media (prefers-reduced-transparency: reduce) { .glass-card-element { background: #1b1b2e; backdrop-filter: none } } — the card turns opaque and the text keeps its contrast.

Browser compatibility

CSS only: backdrop-filter (with -webkit-backdrop-filter), filter: blur(), @keyframes, flexbox, calc(). Zero JavaScript, zero dependency. Backdrop blur ships in Chrome 76+, Edge 79+, Firefox 103+ and Safari 9+ (prefixed; unprefixed since Safari 18). Measured in Chromium 151: blur painted, hover at −4 px. In Firefox 153 and WebKit 26.5 (Playwright), CSS.supports('backdrop-filter', 'blur(1px)') is true and the computed value is blur(20px), but their automated screenshots paint no backdrop blur at all, even on a minimal test page: the blur itself could only be seen in Chromium. Layout, orbs, animation and hover are identical in both engines tested.

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, hover replaced by tap
Android Chrome 76+✓ Full

Without backdrop-filter (Firefox before 103), the card stays a 7% white veil over the orbs, which are already blurred by filter: blur(40px): the frosted look weakens but the text stays readable on the scene's dark backdrop. Over a real, sharp photo, plan a more opaque tint inside @supports not (backdrop-filter: blur(1px)).

The code

Copy the three blocks into your page. No dependencies.

HTML
<div class="glass-card-scene">
    <div class="glass-card-orb glass-card-orb--1"></div>
    <div class="glass-card-orb glass-card-orb--2"></div>
    <div class="glass-card-orb glass-card-orb--3"></div>
    <div class="glass-card-element">
      <h3>Glass Card</h3>
      <p>Hover for the effect</p>
    </div>
  </div>
CSS
.glass-card-scene {
  width: 320px;
  height: 220px;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #080812;
  border-radius: 20px;
  overflow: hidden;
}

.glass-card-orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(40px);
  animation: glassOrbFloat 6s ease-in-out infinite;
}

.glass-card-orb--1 {
  width: 120px;
  height: 120px;
  background: #8b5cf6;
  top: 10px;
  left: 20px;
  animation-delay: 0s;
}

.glass-card-orb--2 {
  width: 100px;
  height: 100px;
  background: #06b6d4;
  bottom: 10px;
  right: 20px;
  animation-delay: -2s;
}

.glass-card-orb--3 {
  width: 80px;
  height: 80px;
  background: #ec4899;
  top: calc(50% - 40px);
  left: calc(50% - 40px);
  animation-delay: -4s;
}

.glass-card-element {
  position: relative;
  z-index: 1;
  width: 260px;
  height: 160px;
  background: rgba(255, 255, 255, 0.07);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-radius: 16px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  cursor: pointer;
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.glass-card-element:hover {
  transform: translateY(-4px);
  box-shadow: 0 12px 40px rgba(139, 92, 246, 0.3);
}

.glass-card-element::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.12) 0%, transparent 50%);
  border-radius: inherit;
  pointer-events: none;
}

.glass-card-element h3 {
  font-size: 1.1rem;
  font-weight: 700;
  color: #fff;
  margin: 0;
}

.glass-card-element p {
  font-size: 0.8rem;
  color: rgba(255, 255, 255, 0.6);
  margin: 0;
}

@keyframes glassOrbFloat {

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

  33% {
    transform: translate(15px, -10px) scale(1.1);
  }

  66% {
    transform: translate(-10px, 15px) scale(0.9);
  }
}
JavaScript (fx-0301)

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
Glass strength (CSS — backdrop-filter: blur(20px) and -webkit-backdrop-filter) 20 px Change both values together. 8–12 px keeps the shapes behind readable (sharp photo, map); 30 px and above keeps only sheets of color. Beyond 40 px there is no visible gain and rendering cost rises on mobile.
Card tint (CSS — .glass-card-element { background: rgba(255,255,255,0.07) }) white at 7% On a dark backdrop, 5–12% white. On a light photo, switch to a dark tint (rgba(20,22,48,.2)): the white text keeps its contrast without making the glass opaque.
Backdrop behind the glass (CSS — .glass-card-scene { background: #080812 }) solid #080812, 320 × 220 px, 20 px corners Replace with your photo (background: url(...) center/cover) or a gradient. Keep the backdrop on this container, not on body: it is what the blur reads, and overflow: hidden keeps the orb halos inside the frame.
Orbs (CSS — .glass-card-orb--1 to --3) violet 120 px, cyan 100 px, pink 80 px, 40 px blur Color, size and position are free. For a centered orb, keep the calc(50% - half the size) form: a transform would be overwritten by the animation. Remove them over a photo if the photo already brings enough color.
Float (CSS — animation: glassOrbFloat 6s ease-in-out infinite) 6 s, offsets 0 / −2 / −4 s, ±15 px, ±10% 10–12 s for barely perceptible motion; increase the keyframe translations (30 px) for a livelier backdrop. The negative offsets keep the three orbs from moving in sync.
Hover (CSS — .glass-card-element:hover) −4 px, violet glow 0 12px 40px at 30%, 0.3 s translateY(-8px) for a clear lift; replace rgba(139,92,246,.3) with your brand color. On a non-clickable card, remove the rule and cursor: pointer.

FAQ

Why does the card have a dark background around it?

Because glass only exists if there is something behind it. Without its own backdrop, pasted into a white page, the card would become an almost white rectangle and its white title would drop to 1.7:1 contrast (measured). That is why the #080812 backdrop is carried by .glass-card-scene, 320 × 220 px with 20 px corners: your page keeps its color and the card always has its backdrop. To put it over a photo, replace that background and stretch the scene (width and height, or position: absolute; inset: 0 in your block), as in the three examples.

How is it different from Frosted Panel (fx-0302)?

Both are free and pure CSS, but one moves and the other doesn't. Glass Card is a card floating above its backdrop: 30 px of space around it, a drop shadow, a diagonal highlight, and it lifts 4 px on hover — an object you put your hand on. Frosted Panel is a still panel filling its frame (30 px inset all round) while three color blobs drift and rotate behind it continuously over 7 to 10 s: the backdrop is what lives, the panel reacts to nothing. Pick Glass Card for an information card over a photo; Frosted Panel for a waiting screen or a "live" box.

Does the blur work in Safari and Firefox?

The property is recognized there: Safari since version 9 with the -webkit-backdrop-filter prefix (included in the code), Firefox since 103. Measured in Firefox 153 and WebKit 26.5 under Playwright, the computed value is indeed blur(20px); however their automated screenshots do not paint that blur, even on a minimal test, so only Chromium could be checked by eye. Without blur, the card stays a light veil over orbs that are already blurred: the effect weakens, the text stays readable.