Anatomie d'une bonne card

Du rectangle mort au composant vivant — 4 étapes pour transformer vos cards avec du hover polish, du tilt 3D, du shimmer holographique. Démos interactives.

La card est le composant le plus utilisé du web. Produits, articles, profils, projets — tout finit dans un rectangle avec une image, un titre et un bouton.

Et pourtant, 90% des cards qu’on croise sont des rectangles morts. Aucun feedback au survol, aucune profondeur, aucune invitation à cliquer. Le contenu est là, mais l’interface ne donne pas envie de l’explorer.

Voici comment passer d’un rectangle plat à un composant qui respire — en 4 étapes.

The card is the most widely used component on the web. Products, articles, profiles, projects — everything ends up in a rectangle with an image, a title, and a button.

And yet, 90% of the cards out there are dead rectangles. No hover feedback, no depth, no invitation to click. The content is there, but the interface doesn’t make you want to explore it.

Here’s how to go from a flat rectangle to a component that breathes — in 4 steps.


Ce qu’il ne faut pas faire

Avant de construire, regardons les erreurs classiques. Chaque card ci-dessous illustre un anti-pattern courant — survole-les pour comprendre le problème.

What not to do

Before building, let’s look at the classic mistakes. Each card below illustrates a common anti-pattern — hover over them to understand the problem.

Le point commun : aucune de ces cards ne donne un feedback clair et maîtrisé. Soit il n’y en a pas, soit il y en a trop, soit il est mal calibré.

The common thread: none of these cards deliver clear, controlled feedback. Either there’s none, there’s too much, or it’s poorly calibrated.


Étape 1 — La fondation propre

Avant tout effet, il faut une base solide : ratio d’image cohérent, typographie lisible, spacing généreux, et surtout — la card entière est cliquable, pas juste le titre.

Le hover est minimal mais intentionnel : un léger translateY(-2px) et une ombre qui s’approfondit. Rien de spectaculaire, mais le cerveau comprend immédiatement que c’est interactif.

Step 1 — A clean foundation

Before any effect, you need a solid base: consistent image ratio, readable typography, generous spacing, and above all — the entire card is clickable, not just the title.

The hover is minimal but intentional: a slight translateY(-2px) and a deepening shadow. Nothing spectacular, but the brain immediately understands it’s interactive.

L’essentiel : 80% de l’impact vient de la structure, pas des effets. Une card bien proportionnée avec un hover subtil bat une card flashy mal construite.

The takeaway: 80% of the impact comes from structure, not effects. A well-proportioned card with a subtle hover beats a flashy, poorly built one every time.


Étape 2 — Le highlight qui guide

On enrichit le hover avec plusieurs indices visuels : une border animée (un conic-gradient qui tourne autour de la card via requestAnimationFrame), un zoom subtil de l’image, une pulsation de l’icône, et des pills qui prennent la couleur d’accent. Chaque couche renforce le feedback sans qu’aucune ne prenne le dessus.

Step 2 — The guiding highlight

We enrich the hover with multiple visual cues: an animated border (a conic-gradient rotating around the card via requestAnimationFrame), a subtle image zoom, an icon pulse, and pills that pick up the accent color. Each layer reinforces the feedback without any one overpowering the rest.

Le ratio effort/impact : la card passe de “propre” à “soignée” avec peu de code en plus. C’est l’étape qui transforme le plus l’expérience pour le moins d’effort.

The effort/impact ratio: the card goes from “clean” to “polished” with very little extra code. This is the step that transforms the experience the most for the least effort.


Étape 3 — Le tilt 3D

La card suit le curseur en 3D : perspective + rotateX/Y calculés à partir de la position de la souris. Un reflet lumineux (radial-gradient) glisse sur la surface, et l’ombre s’adapte à l’angle d’inclinaison — comme un objet physique sous une lampe.

Step 3 — The 3D tilt

The card follows the cursor in 3D: perspective + rotateX/Y computed from the mouse position. A light reflection (radial-gradient) glides across the surface, and the shadow adapts to the tilt angle — like a physical object under a lamp.

L’effet wow : le tilt transforme un élément plat en objet tangible. Le cerveau interprète la perspective et le reflet comme de la profondeur réelle. C’est le pattern qu’on retrouve sur les cards de jeux (Steam, Epic) et les landing pages premium.

The wow factor: the tilt transforms a flat element into a tangible object. The brain interprets the perspective and reflection as real depth. This is the pattern found on game store cards (Steam, Epic) and premium landing pages.


Étape 4 — Le shimmer premium

On passe au niveau supérieur avec useMotionValue + useSpring de Motion : le tracking du curseur ne provoque aucun re-render React — tout passe par des motion values chainées via useTransform.

Chaque couche de la card bouge à une amplitude différente : l’image (±8px), l’icône (±6px), le titre (±5px), la description (±3px), le badge en contre-parallaxe (±3px inversé). Le cerveau perçoit de la profondeur réelle, comme des calques empilés.

En plus du tilt 3D et du shimmer holographique : un glow coloré qui suit le curseur (via useMotionTemplate), une border qui prend la couleur d’accent au hover, et des pills qui apparaissent en cascade avec un délai progressif.

Step 4 — The premium shimmer

We level up with useMotionValue + useSpring from Motion: cursor tracking causes zero React re-renders — everything flows through motion values chained via useTransform.

Each layer of the card moves at a different amplitude: the image (±8px), the icon (±6px), the title (±5px), the description (±3px), the badge in counter-parallax (±3px inverted). The brain perceives real depth, like stacked layers.

On top of the 3D tilt and holographic shimmer: a colored glow that follows the cursor (via useMotionTemplate), a border that takes the accent color on hover, and pills that cascade in with a progressive delay.

Quand l’utiliser : réservé aux éléments “hero” ou premium. Trop de shimmer tue le shimmer — un ou deux éléments par page, pas plus. Le vrai gain ici est la performance : zéro re-render pendant le mouvement de souris.

When to use it: reserved for “hero” or premium elements. Too much shimmer kills the shimmer — one or two elements per page, no more. The real win here is performance: zero re-renders during mouse movement.


Le récap

The recap

Le conseil : commence par l’étape 2. C’est elle qui transforme le plus l’expérience pour le moins de code. L’étape 3 est le wow factor pour les pages qui le méritent. L’étape 4 est la cerise — à doser avec parcimonie.

The advice: start with step 2. It transforms the experience the most for the least code. Step 3 is the wow factor for pages that deserve it. Step 4 is the cherry on top — use sparingly.


Et sur mobile ?

Pas de curseur = pas de hover. Mais le besoin de feedback reste le même. Voici les équivalents tactiles :

  • Press state : au toucher, la card se compresse légèrement (scale(0.97)) — c’est le pendant du translateY au hover. Le cerveau comprend “j’appuie sur un bouton”.
  • Scroll jiggle : au scroll, chaque card oscille subtilement — un micro-tilt en rotateX et un léger rebond vertical, proportionnels à la vitesse de défilement. Le contenu interne (image, titre, description, pills) réagit lui aussi avec un décalage progressif entre les couches, comme des objets empilés qui absorbent l’inertie. L’effet est discret : on le ressent plus qu’on ne le voit.

Tout repose sur un système de ressorts maison en requestAnimationFrame — pas de librairie d’animation, zéro re-render pendant le scroll.

Essaie de scroller et de cliquer les cards ci-dessous :

What about mobile?

No cursor = no hover. But the need for feedback remains the same. Here are the touch equivalents:

  • Press state: on touch, the card compresses slightly (scale(0.97)) — the counterpart of translateY on hover. The brain understands “I’m pressing a button”.
  • Scroll jiggle: on scroll, each card oscillates subtly — a micro-tilt in rotateX and a slight vertical bounce, proportional to scroll speed. The inner content (image, title, description, pills) also reacts with a progressive offset between layers, like stacked objects absorbing inertia. The effect is subtle: you feel it more than you see it.

Everything relies on a custom spring system in requestAnimationFrame — no animation library, zero re-renders during scroll.

Try scrolling and tapping the cards below:

La règle : sur mobile, le feedback doit être instantané et physique. Le press state répond en 150ms, le jiggle est continu et proportionnel à la vitesse du doigt. Pas besoin de hover pour donner de la vie — le scroll lui-même devient l’interaction.

The rule: on mobile, feedback must be instant and physical. The press state responds in 150ms, the jiggle is continuous and proportional to finger speed. No need for hover to bring life — scrolling itself becomes the interaction.


Les démos desktop utilisent Motion pour les animations, la démo mobile repose sur du pur requestAnimationFrame avec des ressorts maison. Pas de librairie de cards, pas de dépendance exotique. Juste des transforms, des gradients, et le bon dosage de feedback.

La prochaine fois que tu styles une card, demande-toi : est-ce qu’elle donne envie d’être cliquée ?

The desktop demos use Motion for animations, while the mobile demo relies on pure requestAnimationFrame with custom springs. No card library, no exotic dependency. Just transforms, gradients, and the right dose of feedback.

Next time you style a card, ask yourself: does it make you want to click it?