DistortionFree

Holographic Card

Dark card with fine stripes where a rainbow shimmer appears and slides in a loop on hover, focus or tap. CSS only.

CSSHoverPremium

Updated

HOLO CARD
Hover or click the scene to interact

This effect is free — the Distortion category contains 31 effects total, including 5 free. Effect.Labs has 840 vanilla effects. Explore the category →

Usage examples

Timetable My card

Student card 2026–2027

Inès Morvan

2nd year · Geography

N° 21 804 337

Hover or tap the card: the moving shimmer shows staff it is the live card, not a screenshot.

With your card

Library loans3 of 10

Canteen balance€12.40

Room access7 am – 10 pm

① Digital student card in a university app (Valcérin)

WhenIn the “My card” tab, the student shows her phone at the library or the canteen; tapping the card sets the shimmer sliding over the photo, the name and the QR code.
WhyA moving shimmer doesn't survive a screenshot: staff can tell at a glance that the card is shown live.
Settings--hlc-w: 266px, --hlc-h: 170px, purple background gradient (--hlc-c1: #1f2150, --hlc-c2: #3b2f6b), transparent root background; the page's CSS lays the card out in a column to hold photo, name and QR code.

Gamebook · Volume I

The Chronicles of Ombrevaine

Collector's edition

Numbered collector's edition

You are the hero, at night

400 numbered sections, a fold-out map of the city and two metal dice. Holographic foil cover, printed only once.

Only 37 copies left out of 500

€49

② Cover of a collector's edition gamebook (Ombrevaine)

WhenOn the pre-order page, the large cover turns iridescent as soon as the mouse passes over it, next to the summary, the remaining stock and the “Pre-order” button.
WhyThe real cover is printed on holographic foil: the shimmer shows online what the buyer will hold in their hands.
Settings196 × 282 px cover, 6px 14px 14px 6px corners like a book spine, #2b1d47 → #0f1830 tones, golden focus outline #e9c46a.

Order · step 2 of 3

How shall we wrap your gift?

Subtotal: €64.00

③ “Holographic paper” option in a gift-wrap choice

WhenAt step 2 of an order, three radio cards offer wrapping; only the holographic option shimmers when hovered or selected with the keyboard.
WhyThe effect works as a sample: it gives an idea of the paper's material, where a plain colour swatch would say nothing.
SettingsThe card is a <label> holding the radio button (no tabindex: the radio's focus switches the shimmer on), 152 × 184 px, 14 px corners.

How it works

The .hlc-card (280 × 180 px) has a midnight-blue gradient background and two layers laid over its content. The ::after pseudo-element draws very light horizontal stripes (3% white, one 2 px line in two). The ::before pseudo-element carries a 125° pink, cyan, yellow, green and purple gradient, twice the card's size, invisible at rest.

On hover, or when the card (or an element inside it) gets focus, this layer fades in over 0.3 s and the hlcShift animation slides it diagonally in 3 seconds, in a loop. It is blended with mix-blend-mode: color-dodge: the colours brighten whatever is beneath, like a holographic film catching the light.

Anything you put in the card goes under the shimmer, as long as you don't give it a position: a positioned child would sit above the layers and would not be iridescent.

Accessibility

  • Keyboard: the card has tabindex="0"; focus switches the shimmer on and shows an outline (--hlc-ring) when it comes from the keyboard. If the card contains a link or button, remove the tabindex: the shimmer also switches on when that element has focus (:focus-within).
  • Touch: tapping the card gives it focus, which switches the shimmer on, including in WebKit where hover doesn't fire under a finger (measured). It goes off when you tap elsewhere.
  • Reduced motion: with prefers-reduced-motion: reduce, the shimmer still appears but stays still, in the middle of its gradient.
  • Contrast: color-dodge strongly brightens text and background when the shimmer is on, even more so in Safari (measured in WebKit). Keep white, bold text on the card and check it is readable with the shimmer on.
  • Nothing hidden: the shimmer is decoration; it carries no information and hides none.

Browser compatibility

CSS only, no JavaScript. Measured in Chromium 151, Firefox 153 and Playwright's WebKit 26.5: 0 errors, two independent copies, hover, Tab, touch, 390 px and reduced motion. In WebKit, color-dodge gives noticeably brighter, more saturated colours than in Chromium and Firefox. Minimum versions per @mdn/browser-compat-data: the layers' inset property sets the floor (Chrome 87, Firefox 66, Safari 14.1).

Chrome 87+✓ Full (measured)
Firefox 66+✓ Full (measured)
Safari 14.1+✓ Full, brighter shimmer (measured in Playwright's WebKit)
Edge 87+✓ Full (Chromium engine)
Safari iOS 14.5+✓ Full, shimmer on tap through focus (measured in touch WebKit)
Chrome Android 87+✓ Full (Chromium engine)

Without inset, replace it with top:0; right:0; bottom:0; left:0 on both pseudo-elements. Without :focus-visible (before Safari 15.4), the focus outline doesn't show but the shimmer still switches on with focus.

The code

Copy the two blocks (HTML and CSS) into your page. No JavaScript, no dependencies.

HTML
<div class="fx-0261-root">
  <div class="hlc-card" tabindex="0">HOLO CARD</div>
</div>
CSS
.fx-0261-root,.fx-0261-root *,.fx-0261-root *::before,.fx-0261-root *::after{box-sizing:border-box}
.fx-0261-root{--hlc-w:280px;--hlc-h:180px;--hlc-radius:16px;--hlc-c1:#1a1a2e;--hlc-c2:#16213e;--hlc-font:1.25rem;--hlc-speed:3s;--hlc-ring:#0ff;--hlc-bg:#0a0a0f;--hlc-min-h:280px;display:flex;align-items:center;justify-content:center;width:100%;min-height:var(--hlc-min-h);position:relative;background:var(--hlc-bg);color:#fff;font-family:sans-serif}
.fx-0261-root .hlc-card{width:var(--hlc-w);max-width:100%;height:var(--hlc-h);background:linear-gradient(135deg,var(--hlc-c1) 0%,var(--hlc-c2) 100%);background-color:var(--hlc-c1);border-radius:var(--hlc-radius);position:relative;overflow:hidden;cursor:pointer;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:var(--hlc-font);outline:none}
.fx-0261-root .hlc-card::before{content:'';position:absolute;inset:0;background:linear-gradient(125deg,transparent 0%,rgba(255,0,128,.3) 15%,rgba(0,255,255,.3) 30%,rgba(255,255,0,.3) 45%,rgba(0,255,128,.3) 60%,rgba(128,0,255,.3) 75%,transparent 100%);background-size:200% 200%;opacity:0;transition:opacity .3s;mix-blend-mode:color-dodge;pointer-events:none}
.fx-0261-root .hlc-card::after{content:'';position:absolute;inset:0;background:repeating-linear-gradient(0deg,transparent,transparent 2px,rgba(255,255,255,.03) 2px,rgba(255,255,255,.03) 4px);pointer-events:none}
.fx-0261-root .hlc-card:hover::before,.fx-0261-root .hlc-card:focus::before,.fx-0261-root .hlc-card:focus-within::before{opacity:1;animation:hlcShift var(--hlc-speed) linear infinite}
.fx-0261-root .hlc-card:focus-visible{outline:2px solid var(--hlc-ring);outline-offset:3px}
@keyframes hlcShift{0%{background-position:0% 0%}100%{background-position:200% 200%}}
@media (prefers-reduced-motion:reduce){.fx-0261-root .hlc-card:hover::before,.fx-0261-root .hlc-card:focus::before,.fx-0261-root .hlc-card:focus-within::before{animation:none;background-position:50% 50%}}
JavaScript

Pure CSS — no JavaScript needed.

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
--hlc-w and --hlc-h 280px and 180px Card size; the width never exceeds the container's.
--hlc-c1 and --hlc-c2 #1a1a2e and #16213e The two colours of the gradient background (the first is also the plain fallback colour). On a light background, color-dodge washes almost everything to white: keep dark tones.
--hlc-speed 3s Duration of one pass of the shimmer.
--hlc-radius 16px Corner rounding; accepts four values (a book spine, for example).
--hlc-font 1.25rem Size of the card's text.
--hlc-ring #0ff Outline colour on keyboard focus.
--hlc-bg and --hlc-min-h #0a0a0f and 280px Root background and minimum height; transparent and 0 to place the card in your page.

FAQ

Why isn't the button I put inside the card iridescent?

It probably has a position (relative, absolute): a positioned child sits above the pseudo-elements. Remove it, or accept that this button stays out of the shimmer, which can also help it stay readable.

Can the shimmer follow the mouse?

No: it always slides diagonally at the same pace, wherever the pointer is. Following the mouse would need JavaScript, which this effect doesn't use.

Can I leave the shimmer on all the time?

Add a class to the card and repeat the active-state rule for it: .fx-0261-root .hlc-card.is-on::before { opacity: 1; animation: hlcShift var(--hlc-speed) linear infinite }.