Holographic Card 3D
Pure CSS holographic card: 3D tilt on hover, rainbow iridescence via conic-gradient and mix-blend-mode — four tunable colors, zero JavaScript.
You'll get access to the interactive demo with a free account.
This effect is part of Effect.Labs — 811 vanilla effects, some free, some premium. Cards has 41 effects, including 6 free. Explore the category →
3 usage examples
How it works
The iridescence relies entirely on the ::after pseudo-element. It stacks two layers: a repeating-linear-gradient(0deg, …) draws horizontal scan lines (1 px white at 7% opacity every 3 px, mimicking holographic foil grain) and a conic-gradient(from 0deg at 50% 50%, c1, c2, c3, c4, c1) cycles through the four configurable colors (--holo-c1 to --holo-c4). Both layers use mix-blend-mode: overlay over the card's dark background — opacity 0 at rest, rising to calc(--holo-intensity * 0.9) on :hover.
The 3D tilt is CSS-only. .holo-stage sets perspective: 1100px. On :hover, the card applies rotateX(calc(var(--holo-tilt)*-1)) rotateY(var(--holo-tilt)) — a symmetric ±--holo-tilt tilt (12° by default) forwards and to the side. The cubic-bezier(.2, .8, .2, 1) transition gives a light spring feel. will-change: transform offloads compositing to the GPU.
The content layer (.holo-content) uses translateZ(40px) with transform-style: preserve-3d on the parent card: text appears visually lifted above the iridescent surface, amplifying the sense of depth and embossed relief.
The gold EMV chip (.holo-chip) is a linear-gradient(135deg, #f4d98b, #b9882f 60%, #f4d98b) with inset and drop shadows simulating brushed metal. Note: the CSS references animation: holo-shift and mix-blend-mode: color-dodge on ::before, but the @keyframes holo-shift and the corresponding background-image are absent from the exported code — the travelling-light animation is inactive; the full holographic render relies on the :hover transition of ::after.
Accessibility
- prefers-reduced-motion absent: no media query disables the tilt or transition. For motion-sensitive users, add
@media (prefers-reduced-motion: reduce) { .holo-card { transition: none } .holo-card::after { transition: none } }. .holo-cardcarriestabindex="0"— the card is keyboard-focusable. No:focus-visiblestyle is defined: add.holo-card:focus-visible { outline: 2px solid var(--holo-c3); outline-offset: 4px; }for keyboard compliance.- No
roleoraria-labelon the card. For semantic use, addrole="img"and anaria-labeldescribing the content (e.g. "Holographic member card, Effect.Labs"). - Text contrast: white (
#fff) and light grey (rgba(255,255,255,0.6)) over dark background (#12121f) — primary text ratio ≥ 15:1, WCAG AAA. - No active JavaScript — no keyboard trap, no interactive behavior beyond CSS hover.
Browser compatibility
The limiting factor is the combination of conic-gradient (Chrome 69+, Firefox 83+, Safari 12.1+) and aspect-ratio (Chrome 88+, Firefox 89+, Safari 15+).
If conic-gradient is not supported, ::after renders nothing (transparent background); the card remains functional with its dark base and gold chip. On mobile, the absence of :hover locks the card in its resting state — the iridescent layers stay hidden.
The code
HTML structure to paste into your page (CSS + JS available with a premium account):
<div class="holo-stage">
<article class="holo-card" tabindex="0">
<div class="holo-content">
<div class="holo-chip"></div>
<div>
<h3>YOUR TITLE</h3>
<p class="holo-sub">Edition subtitle</p>
</div>
<div class="holo-num">0000 · 0000 · LABEL</div>
</div>
</article>
</div>
Full HTML + CSS + JS, copy-paste ready — with hundreds of premium effects.
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
| --holo-c1 to --holo-c4 | #ff2d75, #2de2ff, #b06bff, #ffe14d | The four colors of the iridescent conic-gradient (pink, cyan, purple, yellow). Redefine on .holo-card or via inline style to customize each card independently. |
| --holo-intensity | 0.55 | Maximum opacity of the iridescent layers (::before and ::after). From 0.3 (subtle) to 0.85 (strong). Exceeding 0.8 is only suitable on dark backgrounds. |
| --holo-tilt | 12deg | 3D rotation angle on hover (rotateX and rotateY). From 6deg (delicate) to 22deg (exaggerated trading-card style). |
| --holo-speed | 6s | Cycle duration of the holo-shift animation on ::before. Has no effect in the exported code (keyframes missing) — useful once you add the @keyframes manually. |
| width on .holo-card | 300px | Card width. Height follows automatically via aspect-ratio: 5/7 (420 px at 300 px). Reduce to 160–220 px for catalogue thumbnails. |
| transition on .holo-card | .55s cubic-bezier(.2,.8,.2,1) | Duration and easing of the tilt. Shorten to .25s ease for a snappy response; lengthen to .9s for a cinematic tilt. |
FAQ
.holo-card is self-contained via CSS custom properties. Redefine the variables inline or via a class: <article class="holo-card" style="--holo-c1:#7c3aed;--holo-c2:#06b6d4">. No JavaScript or unique identifier needed — instances share no state.:hover does not persist. The card stays in its resting state (dark base, gold chip, text). To trigger the effect on tap, add a JS listener: card.addEventListener('touchstart', () => card.classList.toggle('is-active')) and define .holo-card.is-active with the same CSS rules as .holo-card:hover.animation: holo-shift var(--holo-speed) linear infinite on ::before, but the @keyframes holo-shift and the background-image for ::before are absent from the exported JSON. To enable it, add to your stylesheet: a background-image: conic-gradient(…) on .holo-card::before and @keyframes holo-shift { from { background-position: 0% 50% } to { background-position: 100% 50% } }.