Neu Card
A 280 px raised card (10 px / 20 px shadows), a 56 px avatar carved into the same material and an 8 px inset gauge filled with a violet gradient that breathes every 2 s: raised and carved in one block, pure CSS.
Updated
This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. Glassmorphism has 47 effects, including 6 free. Explore the category →
3 usage examples



How it works
Three depth levels, all in the #e0e5ec tint. The .neu-card card (280 px wide, padding: 28px, border-radius: 20px, flex column with a 16 px gap) rises from the surface through two opposite shadows: #b8bec7 10px 10px 20px and #fff -10px -10px 20px. On hover they widen to 14 px / 28 px in 0.3 s: the card lifts toward the pointer. The .neu-card-avatar (56 px, round) does the opposite: inset shadows inset 4px 4px 8px, it is carved into the card, and its SVG icon is drawn in violet #8b5cf6 at 1.5 px. The h3 title (16 px, 700, #374151) and the text (13.1 px, #6b7280, line height 1.5) have no effect of their own.
The .neu-card-bar gauge is an 8 px groove (2 px / 4 px inset shadows, overflow: hidden). Its .neu-card-bar-fill covers 72% by default, gradient #8b5cf6 → #a78bfa with an 8 px violet glow, and runs the neuBarPulse animation: opacity 1 → 0.7 → 1 over 2 s, ease-in-out, looping. It is the effect's only motion — it marks a “live” value (a charge, a progress) without moving anything. The rate changes in one line: width on the fill.
The card brings its own surface, because neumorphism depends entirely on the background: set on a black such as #0a0a0f, the #fff -10px -10px 20px shadow would draw a white glow all around it, the opposite of relief. .neu-card-scene therefore declares background: #e0e5ec, padding: 44px (enough for the hover shadow, 14 + 28 = 42 px) and border-radius: 24px. Measured in Chromium and Firefox, pasted into a white then a black page: the light shadow falls on the material, nothing spills onto the page background.
Accessibility
- prefers-reduced-motion not in the code: the gauge pulse loops even when the system asks for less motion. It is gentle (opacity only, no movement) but endless: add
@media (prefers-reduced-motion: reduce) { .neu-card-bar-fill { animation: none } }; the gauge stays fully readable. - Contrast: the
#374151title on#e0e5ecmeasures 8.1:1, but the#6b7280text (13.1 px) only 3.8:1, below the 4.5:1 threshold — switch it to#4b5563(6.0:1). The violet fill against the groove goes from 3.3:1 at the start to 2.2:1 at the end of the gradient (#a78bfa), below the 3:1 required for graphics: for a gauge that carries information, end the gradient on#7c3aedor write the value out. The card's edges only exist through the#b8bec7shadow (1.5:1): do not rely on the card's shape alone to carry important information. - Silent gauge:
.neu-card-baris adivwith no role; a screen reader says nothing about it. Addrole="progressbar",aria-valuenow,aria-valuemin,aria-valuemaxand anaria-label, or write the value under the gauge (“Battery 72%”) — the three scenes do both. - Icon: the avatar SVG has no text alternative; if it is decorative, set
aria-hidden="true". The card is not interactive (hover is purely visual): nothing to reach with the keyboard, and if you make it clickable, wrap it in a real link or button.
Browser compatibility
CSS only: multiple and inset box-shadow, linear-gradient, @keyframes on opacity, flexbox with gap. Zero JavaScript, zero dependencies. Rendering measured identical in Chromium, Firefox and WebKit (Playwright). Flex gap needs Chrome 84, Firefox 63, Safari 14.1. The card is 280 px including padding because the code's .demo-preview block sets box-sizing: border-box; if you drop that block it becomes 336 px (280 + 2 × 28) — add box-sizing: border-box to .neu-card to keep 280.
Before flex gap, the card's items stick together: add margins if you target Safari 14.0 or older. Without CSS animations, the gauge stays full and still.
The code
HTML structure to paste into your page (the CSS + JS come with Premium):
<div class="demo-preview">
<div class="neu-card-scene">
<div class="neu-card">
<div class="neu-card-avatar"><svg viewBox="0 0 24 24">…</svg></div>
<h3>…</h3>
<p>…</p>
<div class="neu-card-bar">
<div class="neu-card-bar-fill"></div>
</div>
</div>
</div>
</div>
The full HTML + CSS + JS of Neu Card, ready to paste — plus all 840 effects. Or $299 once, lifetime access.
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
Gauge rate (CSS — .neu-card-bar-fill { width: 72% }) |
72% | Set the value inline (style="width: 40%") or from JavaScript; update aria-valuenow at the same time. |
Pulse (CSS — animation: 2s … neuBarPulse, opacity 1 → 0.7) |
2 s, looping | animation: none for a fixed gauge (goal reached, charge complete). Slowing to 3s calms it; dropping the low opacity under 0.5 makes it blink. |
Card relief (CSS — 10px 10px 20px, hover 14px 14px 28px) |
10 px / 20 px | Reduce to 6 px / 12 px for a list of tightly packed cards. The padding of .neu-card-scene must stay above the hover offset + blur (42 px by default, hence 44 px). |
Material tint (CSS — #e0e5ec, shadows #b8bec7 / #fff) |
light bluish gray | Change background, card, avatar and groove together, with a darker and a lighter shadow from the same family. Cream example: #efe9e1, shadows #d3cbc0 and #ffffff. |
Gauge color (CSS — linear-gradient(135deg, #8b5cf6, #a78bfa)) |
violet | Battery green #16a34a → #4ade80, amber #d97706 → #fbbf24. Also change the glow box-shadow: rgba(…, .4) 0 0 8px and the avatar icon (stroke). |
FAQ
.neu-card-bar-fill { width: 72% } in the sold code. Write yours inline (style="width: 40%") or from JavaScript: fill.style.width = value + '%'. For the bar to slide instead of jumping, add transition: width .4s ease to the fill. Also give the bar a meaning for screen readers: role="progressbar", aria-valuemin="0", aria-valuemax="100" and aria-valuenow on .neu-card-bar, updated with the width. Once the value is reached, animation: none stops the breathing.gap of at least 40 px so the shadows do not overlap) rather than repeating .neu-card-scene around each one.