Animation CSS avancée avec Claude Code : performance, accessibilité, tests
Guide pratique pour créer des animations CSS rapides, accessibles et vérifiables avec Claude Code.
Une animation CSS doit expliquer, pas seulement bouger
Claude Code peut générer un fondu, un glissement ou un skeleton loader très vite. La vraie difficulté commence quand cette animation arrive en production. Elle doit aider l’utilisateur à comprendre ce qui vient de changer, rester fluide, respecter les personnes qui préfèrent moins de mouvement et rester maintenable dans un design system.
Ce guide aborde l’animation CSS avancée par la pratique : différence entre transition et keyframes, intérêt de transform et opacity, notion de layout thrash, prise en charge de prefers-reduced-motion, animations d’entrée et liées au scroll, états skeleton, tokens de mouvement, prompt de revue pour Claude Code et vérification visuelle avec Playwright.
Quelques définitions simples : une transition interpole deux états, par exemple un bouton au survol. Les keyframes décrivent une ligne de temps avec des étapes comme 0%, 60% et 100%. Le layout thrash apparaît quand le navigateur recalcule plusieurs fois tailles et positions à cause de changements CSS ou JavaScript. Les tokens de mouvement sont des valeurs nommées, comme --motion-duration-fast, pour garder durée, easing et distance cohérents.
Pour prolonger le sujet, consultez aussi l’optimisation des performances avec Claude Code, les variables CSS avec Claude Code et l’accessibilité avec Claude Code.
Choisir transition ou keyframes sans ambiguïté
Utilisez une transition pour les petits changements d’état : hover, focus, active, selected, expanded ou disabled. Utilisez des keyframes quand le déroulé intermédiaire compte : apparition d’un panneau, boucle de chargement, notification progressive, barre de lecture ou reveal au scroll.
Cette règle doit être donnée à Claude Code. Si le prompt dit seulement “anime cette interface”, le code peut animer top, left, height ou margin. Ces propriétés peuvent forcer le recalcul du layout et créer des saccades. Une meilleure consigne est : transition pour les états interactifs, keyframes pour les lignes de temps, transform et opacity en priorité.
:root {
--motion-duration-fast: 160ms;
--motion-duration-normal: 280ms;
--motion-ease-standard: cubic-bezier(0.2, 0, 0, 1);
--motion-distance-sm: 12px;
}
.button {
transition:
background-color var(--motion-duration-fast) var(--motion-ease-standard),
transform var(--motion-duration-fast) var(--motion-ease-standard);
}
.button:hover {
transform: translateY(-2px);
}
.notice {
opacity: 0;
transform: translateY(var(--motion-distance-sm));
animation: notice-enter var(--motion-duration-normal) var(--motion-ease-standard) forwards;
}
@keyframes notice-enter {
from {
opacity: 0;
transform: translateY(var(--motion-distance-sm));
}
to {
opacity: 1;
transform: translateY(0);
}
}
Le bouton utilise une transition car il réagit à un état direct. La notification utilise des keyframes car son entrée est conçue comme une séquence. Pour vérifier la syntaxe, les pages MDN CSS animations et transform restent les références officielles.
La performance commence par transform et opacity
Pour produire une image, le navigateur passe par layout, paint et composition. Le layout calcule la géométrie, paint dessine les pixels et composition assemble les calques. Animer transform et opacity reste souvent dans la composition, ce qui est généralement plus fluide.
Animer width, height, margin, top ou left peut modifier les éléments voisins. Si JavaScript lit ensuite des dimensions et écrit de nouveaux styles dans une boucle, le layout thrash apparaît. Dans React, gardez donc les classes d’animation simples et faciles à tester.
import type { ReactNode } from "react";
import "./motion.css";
type AnimatedPanelProps = {
children: ReactNode;
isOpen: boolean;
};
export function AnimatedPanel({ children, isOpen }: AnimatedPanelProps) {
return (
<section
className={isOpen ? "panel panel-enter" : "panel"}
aria-hidden={!isOpen}
>
{children}
</section>
);
}
.panel {
opacity: 0;
transform: translateY(12px) scale(0.98);
pointer-events: none;
}
.panel-enter {
animation: panel-enter 220ms cubic-bezier(0.2, 0, 0, 1) forwards;
pointer-events: auto;
}
@keyframes panel-enter {
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
will-change n’est pas une solution magique. Il peut aider juste avant une animation, mais le laisser partout consomme de la mémoire. Le guide web.dev sur la performance des animations rappelle que le choix des propriétés animées est essentiel.
Cas d’usage concrets
Premier cas : apparition de cartes, de tarifs ou de modules de tableau de bord. Une entrée courte guide le regard. Une cascade lente sur toutes les cartes retarde seulement la lecture. Limitez les délais et gardez le contenu visible si l’animation ne se lance pas.
Deuxième cas : feedback lié au scroll, comme une barre de progression de lecture ou l’apparition d’une section. animation-timeline est pratique, mais il faut une dégradation correcte. Si le navigateur ne le prend pas en charge, la page doit rester lisible.
.scroll-progress {
position: fixed;
inset: 0 auto auto 0;
z-index: 20;
width: 100%;
height: 3px;
transform-origin: left;
transform: scaleX(0);
background: var(--color-accent, #2563eb);
}
@supports (animation-timeline: scroll()) {
.scroll-progress {
animation: progress-grow linear both;
animation-timeline: scroll();
}
}
@keyframes progress-grow {
to {
transform: scaleX(1);
}
}
.reveal {
opacity: 1;
transform: none;
}
@supports (animation-timeline: view()) {
.reveal {
opacity: 0;
transform: translateY(16px);
animation: reveal-up 1ms linear both;
animation-timeline: view();
animation-range: entry 10% cover 30%;
}
}
@keyframes reveal-up {
to {
opacity: 1;
transform: translateY(0);
}
}
Troisième cas : skeleton et états de chargement. Un skeleton réduit l’incertitude, mais un shimmer trop visible finit par fatiguer. Pour les opérations longues, ajoutez un texte de statut, une relance ou une annulation.
Quatrième cas : feedback dans un outil SaaS. Enregistrement terminé, filtre appliqué, élément déplacé ou panneau d’erreur ouvert peuvent profiter d’une animation courte. Dans une interface utilisée toute la journée, la stabilité passe avant l’effet spectaculaire.
Respecter reduced motion et savoir ne pas animer
prefers-reduced-motion permet de tenir compte de la préférence utilisateur pour moins de mouvement. Ce n’est pas optionnel : certaines personnes ressentent fatigue, gêne ou distraction face aux animations fortes. La référence MDN prefers-reduced-motion décrit le comportement attendu.
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
scroll-behavior: auto !important;
animation-duration: 1ms !important;
animation-delay: 0ms !important;
animation-iteration-count: 1 !important;
transition-duration: 1ms !important;
}
.scroll-progress {
animation: none;
transform: scaleX(1);
}
.skeleton {
animation: none;
background-image: none;
}
}
Certaines zones ne devraient presque jamais être animées : confirmation de paiement, mentions légales, erreurs critiques de formulaire, long texte de lecture, tableaux denses et menus ouverts des dizaines de fois par jour. Ici, la clarté immédiate vaut mieux que le mouvement.
Demander à Claude Code une vraie revue
Ne demandez pas seulement d’ajouter un effet. Demandez une revue des risques. Ce prompt sert de checklist :
Review and improve the CSS animation implementation for this UI.
Requirements:
- Use transition for simple hover/focus/open states.
- Use keyframes only when intermediate timing matters.
- Animate transform and opacity first; avoid top, left, width, height, and margin animations.
- Add design tokens for duration, easing, and distance.
- Respect prefers-reduced-motion.
- Keep content visible when scroll-linked animation is unsupported.
- Do not animate critical form errors, payment confirmation, or long reading content.
Return:
1. Risky selectors and why they are risky.
2. A corrected CSS/React implementation.
3. Manual and Playwright checks to verify overflow and reduced motion.
Claude Code cherchera ainsi layout thrash, boucles infinies, excès de will-change, fallback manquant et préférence utilisateur ignorée.
Vérifier avec Playwright
Les bugs d’animation sont souvent visuels. Ajoutez des vérifications ciblées pour le débordement horizontal, la visibilité du contenu et le mode reduced motion.
import { expect, test } from "@playwright/test";
test("animated page has no horizontal overflow", async ({ page }) => {
await page.goto("/animation-demo");
const overflow = await page.evaluate(() => {
return document.documentElement.scrollWidth > window.innerWidth;
});
expect(overflow).toBe(false);
});
test("reduced motion keeps content visible", async ({ browser }) => {
const context = await browser.newContext({ reducedMotion: "reduce" });
const page = await context.newPage();
await page.goto("/animation-demo");
await expect(page.locator(".reveal").first()).toBeVisible();
await expect(page.locator(".skeleton").first()).toHaveCSS("animation-name", "none");
await context.close();
});
Pour les écrans sensibles, ajoutez des captures desktop et mobile. Les tests ne remplacent pas le jugement design, mais ils repèrent contenu caché, scroll horizontal et mode reduced motion ignoré.
Résumé et prochaine étape
Une animation CSS de production commence par une intention claire. Transition pour les petits états, keyframes pour les lignes de temps, transform et opacity pour la fluidité, tokens pour la cohérence, reduced motion pour l’accessibilité et Playwright pour les garde-fous visuels. Claude Code produit de meilleurs résultats quand ces contraintes sont explicites.
Choisissez maintenant une liste de cartes ou une section CTA existante, puis appliquez les tokens, l’animation d’entrée, la règle reduced motion et les tests de cet article. Pour une revue plus complète, consultez formation et conseil.
Note de vérification : en limitant le mouvement à transform et opacity, aucun débordement horizontal n’est apparu. En reduced motion avec Playwright, le contenu .reveal est resté visible et le skeleton n’avait plus d’animation. Dans une interface métier, un shimmer long semblait ralentir la perception du chargement ; un placeholder discret est souvent préférable.
PDF gratuit: cheatsheet Claude Code
Saisissez votre email et téléchargez une page avec commandes, habitudes de review et workflow sûr.
Nous protégeons vos données et n'envoyons pas de spam.
À propos de l'auteur
Masa
Ingénieur spécialisé dans les workflows pratiques avec Claude Code.
Articles liés
Permission receipt Claude Code : portée, preuves et rollback
Modèle de permission receipt pour Claude Code : actions autorisées, limites d'approbation, commandes de preuve, rollback et CTAs revenus.
Agent Harness securise pour Claude Code et Codex : permissions, verification et rollback
Construisez un Agent Harness pratique pour Claude Code et Codex avec politiques, plan, verification et recuperation.
Sous-agents Claude Code : guide pratique pour déléguer sans perdre le contrôle
Guide pratique des sous-agents Claude Code pour répartir articles et code : règles, prompts, pièges et checklist.