Student card 2026–2027
Inès Morvan
2nd year · Geography
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
Dark card with fine stripes where a rainbow shimmer appears and slides in a loop on hover, focus or tap. CSS only.
Updated
This effect is free — the Distortion category contains 31 effects total, including 5 free. Effect.Labs has 840 vanilla effects. Explore the category →
Student card 2026–2027
Inès Morvan
2nd year · Geography
Hover or tap the card: the moving shimmer shows staff it is the live card, not a screenshot.
Library loans3 of 10
Canteen balance€12.40
Room access7 am – 10 pm
Gamebook · Volume I
The Chronicles of Ombrevaine
Collector's edition
Numbered collector's edition
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
Order · step 2 of 3
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.
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).prefers-reduced-motion: reduce, the shimmer still appears but stays still, in the middle of its gradient.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.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).
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.
Copy the two blocks (HTML and CSS) into your page. No JavaScript, no dependencies.
<div class="fx-0261-root">
<div class="hlc-card" tabindex="0">HOLO CARD</div>
</div>
.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%}}
Pure CSS — no JavaScript needed.
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
--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. |
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.
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.
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 }.