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.
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.
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>
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.
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>
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.
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.
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.
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.