SolutionsCase StudiesAI ToolsResourcesAboutContact
Get Your Free AI Automation Audit Book a Free 30-Minute Strategy Call
Playground~/frontend Open editor

~/css/animated-cards

7 CSS Animated Cards

6 Pure CSS1 with JSPublished 2026-10-05Free · no sign-up

Seven card animations that add meaning rather than noise: a product card that lifts, a destination card that reveals details, cards that arrive one after another, a spotlight that follows the cursor, a card that expands to show more, a holographic shine and a recipe card whose cover folds up.

01. Lift and Zoom Product Card

CardHover

The card rises a few pixels and its shadow deepens on hover, while the image area zooms slightly inside a fixed frame. The whole card is one link, so the hover and focus states belong to the same element and the click target is generous.

View code
<a class="ac1" href="#lamp"><div class="img" aria-hidden="true"><span></span></div><div class="b"><p class="k">Lighting</p><h3>Arc floor lamp</h3><p class="p">$189</p></div></a>
.ac1 { display: block; width: 260px; max-width: 100%; box-sizing: border-box; border: 1px solid #e4e7ec; border-radius: 16px; background: #fff; color: #101828; text-decoration: none; overflow: hidden; font-family: Inter, system-ui, sans-serif; box-shadow: 0 1px 2px rgba(16,24,40,.06); transition: transform .3s ease, box-shadow .3s ease; }
.ac1 .img { height: 150px; overflow: hidden; }
.ac1 .img span { display: block; height: 100%; background: radial-gradient(circle at 70% 30%, #fde68a 0 18%, transparent 19%), linear-gradient(160deg, #e0e7ff, #c7d2fe); transition: transform .5s ease; }
.ac1 .b { padding: 14px 16px 16px; }
.ac1 .k { margin: 0; color: #6941c6; font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; }
.ac1 h3 { margin: 4px 0; font-size: 17px; }
.ac1 .p { margin: 0; color: #344054; font-weight: 700; }
.ac1:hover, .ac1:focus-visible { transform: translateY(-4px); box-shadow: 0 18px 32px -14px rgba(16,24,40,.35); }
.ac1:hover .img span, .ac1:focus-visible .img span { transform: scale(1.06); }
.ac1:focus-visible { outline: 3px solid #7f56d9; outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) { .ac1, .ac1 .img span { transition: none; } .ac1:hover, .ac1:focus-visible { transform: none; } .ac1:hover .img span { transform: none; } }

02. Details Slide Up on Hover

CardReveal

A destination card that shows only the title until hovered or focused, when a panel with the description and a link slides up. The panel uses :focus-within as well as :hover, so keyboard users reach the link and the details appear for them too. On touch screens the panel is always shown.

View code
<article class="ac2"><div class="bg" aria-hidden="true"></div><div class="panel"><h3>Lofoten, Norway</h3><div class="more"><div><p>Fishing villages under steep peaks, best from June to August.</p><a href="#lofoten">Read the guide</a></div></div></div></article>
.ac2 { position: relative; width: 260px; max-width: 100%; height: 300px; border-radius: 18px; overflow: hidden; font-family: Inter, system-ui, sans-serif; color: #fff; }
.ac2 .bg { position: absolute; inset: 0; background: linear-gradient(180deg, transparent 40%, rgba(2,6,23,.85)), linear-gradient(200deg, #0ea5e9, #1e3a8a 55%, #0f172a); }
.ac2 .panel { position: absolute; left: 0; right: 0; bottom: 0; padding: 18px; }
.ac2 h3 { margin: 0; font-size: 20px; }
.ac2 .more { display: grid; grid-template-rows: 0fr; opacity: 0; transition: grid-template-rows .35s ease, opacity .35s ease; }
.ac2 .more > div { min-height: 0; overflow: hidden; }
.ac2 p { margin: 8px 0 10px; color: #dbeafe; font-size: 14px; line-height: 1.45; }
.ac2 a { color: #fff; font-weight: 700; font-size: 14px; }
.ac2:hover .more, .ac2:focus-within .more { grid-template-rows: 1fr; opacity: 1; }
.ac2 a:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
@media (hover: none) { .ac2 .more { grid-template-rows: 1fr; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .ac2 .more { transition: none; } }

03. Staggered Entrance

CardEntrance

Three stat cards fade and rise into place one after another when the page loads, using one keyframe animation and a custom property for each card's delay. The final state is the normal layout, so nothing is hidden if the animation never runs.

View code
<ul class="ac3"><li style="--i:0"><b>2.4k</b><span>Orders</span></li><li style="--i:1"><b>98%</b><span>On time</span></li><li style="--i:2"><b>4.8</b><span>Rating</span></li></ul>
.ac3 { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin: 0; padding: 0; list-style: none; font-family: Inter, system-ui, sans-serif; box-sizing: border-box; max-width: 100%; }
.ac3 li { display: grid; width: 92px; padding: 16px 12px; border: 1px solid #e4e7ec; border-radius: 14px; background: #fff; text-align: center; animation: ac3 .6s cubic-bezier(.2,.7,.2,1) both; animation-delay: calc(var(--i) * 140ms); }
.ac3 b { color: #101828; font-size: 22px; }
.ac3 span { color: #475467; font-size: 13px; }
@keyframes ac3 { from { opacity: 0; transform: translateY(18px); } }
@media (prefers-reduced-motion: reduce) { .ac3 li { animation: none; } }

04. Cursor Spotlight Card

CardJavaScript

A soft light follows the pointer across a dark feature card. Script stores the pointer position in two custom properties and a radial gradient in a pseudo-element reads them, so the effect costs one style update per move. It fades out when the pointer leaves.

View code
<article class="ac4"><h3>Instant previews</h3><p>Every change you make shows up in the preview before you finish typing.</p></article>
.ac4 { --x: 50%; --y: 50%; position: relative; width: 280px; max-width: 100%; box-sizing: border-box; padding: 26px 22px; border: 1px solid #263048; border-radius: 18px; background: #111727; font-family: Inter, system-ui, sans-serif; overflow: hidden; }
.ac4::before { content: ""; position: absolute; inset: 0; background: radial-gradient(220px circle at var(--x) var(--y), rgba(56,189,248,.18), transparent 70%); opacity: 0; transition: opacity .3s; pointer-events: none; }
.ac4:hover::before { opacity: 1; }
.ac4 h3 { position: relative; margin: 0 0 8px; color: #f1f5ff; font-size: 18px; }
.ac4 p { position: relative; margin: 0; color: #a8b3cf; font-size: 14px; line-height: 1.55; }
var c = document.querySelector('.ac4');
c.addEventListener('pointermove', function (e) {
  var r = c.getBoundingClientRect();
  c.style.setProperty('--x', e.clientX - r.left + 'px');
  c.style.setProperty('--y', e.clientY - r.top + 'px');
});

05. Expanding Card with details

CardDisclosure

A plan card built on details and summary, so expanding it needs no script and works with the keyboard. The extra rows animate open with interpolate-size where the browser supports it, and simply appear elsewhere. The chevron turns with the open state.

View code
<details class="ac5"><summary><span><b>Team plan</b><small>$12 per seat / month</small></span><i aria-hidden="true"></i></summary><ul><li>Unlimited projects</li><li>Shared libraries</li><li>Priority support</li></ul></details>
.ac5 { width: 280px; max-width: 100%; box-sizing: border-box; border: 1px solid #d0d5dd; border-radius: 14px; background: #fff; font-family: Inter, system-ui, sans-serif; color: #101828; interpolate-size: allow-keywords; }
.ac5 summary { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 16px 18px; cursor: pointer; list-style: none; border-radius: 14px; }
.ac5 summary::-webkit-details-marker { display: none; }
.ac5 summary span { display: grid; } .ac5 small { color: #475467; font-size: 13px; }
.ac5 i { width: 10px; height: 10px; border-right: 2px solid #475467; border-bottom: 2px solid #475467; transform: rotate(45deg); transition: transform .25s; }
.ac5[open] i { transform: rotate(-135deg); }
.ac5::details-content { height: 0; overflow: hidden; transition: height .3s ease, content-visibility .3s allow-discrete; }
.ac5[open]::details-content { height: auto; }
.ac5 ul { margin: 0; padding: 0 18px 16px 36px; color: #344054; font-size: 14px; line-height: 1.8; }
.ac5 summary:focus-visible { outline: 3px solid #84adff; outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { .ac5::details-content, .ac5 i { transition: none; } }

06. Holographic Shine Card

CardGradient

A collectible-style card with a rainbow sheen that slides across it on hover. The sheen is a wide repeating gradient in a blended pseudo-element whose background-position moves, so no image or canvas is needed.

View code
<article class="ac6"><p class="t">Founder member</p><p class="n">#0042</p><p class="o">Ana Ribeiro</p></article>
.ac6 { position: relative; display: grid; align-content: space-between; width: 240px; max-width: 100%; box-sizing: border-box; aspect-ratio: 5 / 7; padding: 20px; border-radius: 18px; background: linear-gradient(150deg, #1e1b4b, #312e81 60%, #4c1d95); color: #fff; font-family: Inter, system-ui, sans-serif; overflow: hidden; }
.ac6::after { content: ""; position: absolute; inset: 0; background: linear-gradient(115deg, transparent 30%, rgba(255,0,128,.35), rgba(0,255,255,.35), rgba(255,255,0,.3), transparent 70%) 0 0 / 250% 250%; mix-blend-mode: color-dodge; opacity: .35; transition: background-position .8s ease, opacity .3s; pointer-events: none; }
.ac6:hover::after { background-position: 100% 100%; opacity: .8; }
.ac6 p { position: relative; margin: 0; }
.ac6 .t { font-size: 12px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: #c7d2fe; }
.ac6 .n { font: 800 44px Inter, system-ui, sans-serif; }
.ac6 .o { font-weight: 600; }
@media (prefers-reduced-motion: reduce) { .ac6::after { transition: none; } }

07. Card That Reveals a Back Face

Card3D

A recipe card whose cover folds up on hover or focus to reveal the ingredients, using a 3D rotation around the top edge. The back content is in the DOM all the time, so screen readers read both faces in order regardless of the animation.

View code
<a class="ac7" href="#bread"><span class="back"><b>You need</b>500g flour · 10g salt · 7g yeast · 350ml water</span><span class="front"><b>Overnight loaf</b><small>Prep 20 min · Rise 12 h</small></span></a>
.ac7 { position: relative; display: block; width: 260px; max-width: 100%; height: 170px; perspective: 800px; font-family: Inter, system-ui, sans-serif; text-decoration: none; }
.ac7 span { position: absolute; inset: 0; display: grid; align-content: center; gap: 6px; padding: 18px; box-sizing: border-box; border-radius: 16px; }
.ac7 .back { background: #fff7ed; border: 1px solid #fed7aa; color: #7c2d12; font-size: 14px; line-height: 1.5; }
.ac7 .front { background: linear-gradient(135deg, #ea580c, #b45309); color: #fff; transform-origin: top; transition: transform .5s ease; backface-visibility: hidden; }
.ac7 .front b { font-size: 20px; } .ac7 small { color: #ffedd5; }
.ac7:hover .front, .ac7:focus-visible .front { transform: rotateX(-105deg); }
.ac7:focus-visible { outline: 3px solid #fb923c; outline-offset: 3px; border-radius: 16px; }
@media (prefers-reduced-motion: reduce) { .ac7 .front { transition: none; } .ac7:hover .front, .ac7:focus-visible .front { transform: none; opacity: 0; } }

About these CSS Animated Cards

Animate cheap properties

Moving and fading cards with transform and opacity keeps animation on the compositor, so it stays smooth on phones. Changing height, top or margin forces layout on every frame.

Hover is not the only state

Anything revealed on hover must also appear on :focus-visible or :focus-within, otherwise keyboard users never see it. On touch screens, where there is no hover, show the details by default with @media (hover: none).

Animating to auto height

The rows trick (grid-template-rows: 0fr to 1fr) animates content to its natural height without measuring it. Newer browsers can also transition height: auto with interpolate-size: allow-keywords.

Entrances should end in the normal layout

Write the final state as the card's normal style and animate from a hidden state with a from keyframe. If the animation never runs, for reduced motion or a slow device, the card is still there.

Frequently asked questions

Do these cards need JavaScript?

Only the spotlight card, which uses a few lines to track the pointer. The others are pure CSS.

Is a whole-card link accessible?

Yes, if the link text is short and the card has no other links inside. Cards with several actions need separate links.

How do I turn the animations off?

Every demo has a prefers-reduced-motion block that removes or shortens its motion.