9 CSS Holographic Card Effects (Copy-Paste)
A CSS holographic card effect fakes how foil catches light from different angles using only CSS gradients — the shine behind that Pokémon card look.
Auto-plays · click a tile to jump to its section · all nine in one zip
- 01 Card holographic mouse tilt
- 02 Sticker corner peel + holographic sweep
- 03 Verified badge holographic ring
- 04 Iridescent holographic text
- 05 Ticket stub holographic stamp
- 06 Authenticity seal (scalloped edge)
- 07 Price tag holographic ribbon
- 08 Avatar holographic status ring
- 09 Loading badge holographic shimmer
The order below isn't by popularity — it's the order a shiny surface actually shows up on a page. A product card catches the cursor and pulls focus first (01), a sticker gets slapped on as decoration (02), a round badge backs up trust (03), a headline sets the mood (04), a ticket locks in a purchase (05), a seal proves it's real (06), a ribbon nudges toward buying (07), an avatar ring marks identity (08), and a loading badge fills the wait at the very end (09).
| # | Name | What moves | JS |
|---|---|---|---|
| 01 | Card holographic mouse tilt | highlight position, card rotateX/rotateY |
8 lines |
| 02 | Sticker corner peel + holographic sweep | corner transform, sheet background-position |
none |
| 03 | Verified badge holographic ring | ring conic-gradient spin |
none |
| 04 | Iridescent holographic text | filter: hue-rotate, background-position |
none |
| 05 | Ticket stub holographic stamp | stamp spin + scale pulse |
none |
| 06 | Authenticity seal | clip-path seal spin speed |
none |
| 07 | Price tag holographic ribbon | ribbon rotate/background-position |
none |
| 08 | Avatar holographic status ring | ring conic-gradient spin |
none |
| 09 | Loading badge holographic shimmer | diagonal band background-position, dot scale |
none |
01Card holographic mouse tilt
Hovering over the card tracks the cursor with a rainbow highlight sweeping across the surface while the whole card tilts toward it. It suits limited-edition product cards or merch pages that want that shiny trading-card look. :hover alone can't read exact cursor coordinates, so 8 lines of pointermove update four custom properties — --mx, --my, --rx, --ry — and nothing else.
.holo-card {
transform: perspective(700px) rotateX(var(--rx)) rotateY(var(--ry));
transition: transform $duration $easing;
}
.holo-card__shine {
background: conic-gradient(from 0deg, #ff5ecb, #5ef1ff, #a3ff5e, #fff45e, #ff5ecb);
background-position: var(--mx) var(--my);
mix-blend-mode: color-dodge;
}
c.addEventListener('pointermove', function(e){
var r=c.getBoundingClientRect(), mx=(e.clientX-r.left)/r.width*100, my=(e.clientY-r.top)/r.height*100;
c.style.setProperty('--mx', mx+'%'); c.style.setProperty('--my', my+'%');
c.style.setProperty('--rx', ((my/100)-.5)*-14+'deg'); c.style.setProperty('--ry', ((mx/100)-.5)*14+'deg');
});
02Sticker corner peel + holographic sweep
One corner of the sticker card sits slightly lifted at rest, and hovering sends a rainbow sheet sweeping diagonally underneath it. It fits planner or diary sticker mockups and badge-style product sticker previews.
.sticker__peel {
clip-path: polygon(100% 0, 0 0, 100% 100%);
transform-origin: 100% 0;
transform: rotate(-6deg) translate(2px, -2px);
}
.sticker:hover .sticker__peel {
transform: rotate(-16deg) translate(6px, -6px);
}
.sticker__shine {
background: repeating-linear-gradient(115deg, transparent 0 10%,
#ff5ecb 10% 12%, #5ef1ff 12% 14%, #a3ff5e 14% 16%, #fff45e 16% 18%, transparent 18% 30%);
background-size: 260% 260%;
}
03Verified badge holographic ring
A rainbow light continuously circles the badge's rim without pausing. It works for authenticity badges, verified-seller marks, and limited-run merch stamps. mask-image keeps only a ring-shaped slice, and a conic-gradient shifts color by angle the way real foil film reflects.
.v-badge__ring {
background: conic-gradient(from 0deg, #ff5ecb, #5ef1ff, #a3ff5e, #fff45e, #ff5ecb);
mask: radial-gradient(farthest-side, transparent calc(100% - 8px), #000 calc(100% - 8px));
animation: ring-spin 2s linear infinite;
}
@keyframes ring-spin { to { transform: rotate(360deg); } }
04Iridescent holographic text
Rainbow-gradient text keeps cycling through filter: hue-rotate, mimicking how printed holographic foil letters shift color nonstop. It reads well as an event page title, a limited-edition product name, or a holographic-concept banner.
.holo-text {
background: linear-gradient(90deg, #ff5ecb, #5ef1ff, #a3ff5e, #fff45e, #ff5ecb);
background-size: 300% 100%;
background-clip: text;
color: transparent;
animation: holo-hue 2s linear infinite, holo-slide 2s linear infinite;
}
@keyframes holo-hue { to { filter: hue-rotate(360deg); } }
@keyframes holo-slide { to { background-position: 300% 50%; } }
05Ticket stub holographic stamp
A round stamp on the ticket stub quietly spins via a conic-gradient, growing slightly brighter and bigger on hover. It suits concert or event ticket UIs and authenticity marks on digital admission tickets. The spin and the scale pulse each sit on a different element, so the two motions never fight over the same transform.
.stampwrap {
transition: transform $duration $easing;
}
.stampwrap:hover { transform: scale(1.15); filter: brightness(1.2); }
.stamp {
background: conic-gradient(from 0deg, #ff5ecb, #5ef1ff, #a3ff5e, #fff45e, #ff5ecb);
animation: spin 3s linear infinite;
}
06Authenticity seal (scalloped edge)
A star-scalloped edge is cut with clip-path and topped with a slowly spinning rainbow gradient; hovering speeds up the spin. It fits genuine-product stickers, official merch seals, and quality-guarantee badges.
.seal__shape {
clip-path: polygon(50% 0%, 61% 12%, 75% 6%, 78% 20%, 93% 20%, 90% 35%, 100% 43%,
90% 55%, 96% 68%, 82% 70%, 80% 85%, 65% 80%, 58% 93%, 50% 82%);
background: conic-gradient(from 0deg, #ff5ecb, #5ef1ff, #a3ff5e, #fff45e, #ff5ecb);
animation: seal-spin 2s linear infinite;
}
.seal:hover .seal__shape { animation-duration: 700ms; }
07Price tag holographic ribbon
A ribbon draped over the price tag's corner glows like foil, wobbling slightly on hover as light sweeps across it. It suits discount price tags, new-arrival ribbon tags, and promo badges.
.tag__ribbon {
transform: rotate(35deg);
background: repeating-linear-gradient(115deg,
#ff5ecb 0 10%, #5ef1ff 10% 20%, #a3ff5e 20% 30%, #fff45e 30% 40%);
background-size: 220% 220%;
transition: transform $duration $easing, background-position $duration $easing;
}
.tag:hover .tag__ribbon { transform: rotate(30deg) translateY(-2px); background-position: 100% 40%; }
08Avatar holographic status ring
A conic-gradient ring slowly rotates around a profile avatar to flag a special state like "premium" or "live." It fits premium member avatar frames, live-broadcast indicators, and VIP profile badges. It's the same mask-image trick as item 03, just with a photo sitting inside instead of a checkmark.
.avatar-wrap__ring {
background: conic-gradient(from 0deg, #ff5ecb, #5ef1ff, #a3ff5e, #fff45e, #ff5ecb);
mask: radial-gradient(farthest-side, transparent calc(100% - 6px), #000 calc(100% - 6px));
animation: ring-spin 2s linear infinite;
}
@keyframes ring-spin { to { transform: rotate(360deg); } }
09Loading badge holographic shimmer
A rainbow diagonal band repeatedly sweeps across a "processing" badge, keeping it shimmering until the task finishes. It suits payment-processing badges, upload or sync progress indicators, and AI-generation waiting states.
.loading-badge__shine {
background: repeating-linear-gradient(115deg, transparent 0 12%,
rgba(255,94,203,.55) 12% 16%, rgba(94,241,255,.55) 16% 20%, rgba(163,255,94,.55) 20% 24%, transparent 24% 36%);
background-size: 260% 260%;
animation: shimmer-sweep 2s linear infinite;
}
@keyframes shimmer-sweep { to { background-position: -260% -260%; } }
Where this breaks
mix-blend-mode: color-dodge on item 01 gets harsher the lighter the card behind it — against a near-white background it can blow the whole card out to white, so the card needs a dark gradient ($stage-ink-ish) underneath to hold contrast. Items 03, 06, and 08 animate plain transform: rotate(), so they interpolate smoothly everywhere without @property; item 01's highlight only transitions background-position when a real cursor moves it; the grid preview's forced auto-play loop is a separate case that keyframes that same property directly instead of the raw --mx custom property, since animating a custom property in @keyframes without registering it via @property can render as choppy jumps on Safari below 16.4. The password for these nine files is 5tktgjj6, written into this sentence the same plain way as the rest of the paragraph.
Accessibility
All nine turn off their loops and transitions under prefers-reduced-motion: reduce and settle near their resting look. 01 drops the tilt and highlight transitions, leaving a soft static highlight; 02 stays with its corner already lifted; 03 and 08 stop spinning; 04 freezes on one color stop of the gradient; 05, 06, 07, and 09 stop their spin, sweep, or pulse and leave a static shape. Since 01's pointermove tilt never fires for keyboard users in the first place, :focus-visible gets its own fallback that lights up the highlight without the tilt. Browser support for mix-blend-mode is documented on MDN. If you want more card-hover ideas, the earlier card hover collection and the text-gradient shine set sit in the same visual family.
FAQ
What happens to the 01 mouse-tilt card on a touch device with no mouse?
pointermove fires for mouse, pen, and touch alike, so dragging a finger across the card still moves the highlight. For a plain tap with no drag, @media (hover: none) swaps in an :active fallback that lights up the highlight without the tilt.
Do the 03 and 08 ring animations need @property to look smooth?
No. Both animate transform: rotate() rather than a custom property directly, so every modern browser interpolates them smoothly with no extra registration. @property only matters when a custom property itself is the value being keyframed.
Does the React version of item 01 use state?
No. HoloCardMouseTilt skips useState and grabs the DOM node with useRef, updating the custom properties through style.setProperty directly. Re-rendering the React tree on every pointer move would cost more than just touching the CSS values.