Créez vos animations CSS keyframes sur mesure : type, durée, timing function. Code CSS prêt à l'emploi.
Générateur d'animations CSS Keyframes
⚙️ Paramètres de l'animation
👁️ Prévisualisation
📋 Code CSS généré
.mon-element à l'élément HTML à animer.
Les animations CSS keyframes : fondamentaux
Les animations CSS permettent de faire évoluer les propriétés d'un élément
HTML dans le temps, sans JavaScript, en déclarant des étapes intermédiaires via la règle
@keyframes. Introduites dans la spécification CSS3, elles sont aujourd'hui
supportées par l'ensemble des navigateurs modernes (Chrome, Firefox, Safari, Edge)
avec un support global dépassant 98% selon Can I Use.
La règle @keyframes définit le scénario de l'animation : quels
styles s'appliquent à quel instant. La propriété animation (ou ses
sous-propriétés) rattache ce scénario à un élément et configure sa durée, son rythme,
son nombre de répétitions et d'autres paramètres.
Syntaxe de base
/* 1. Déclarer le scénario */
@keyframes monAnimation {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* 2. Appliquer à un élément */
.mon-element {
animation: monAnimation 0.6s ease-out forwards;
}
Les étapes peuvent être définies via les mots-clés from et to
(équivalents à 0% et 100%), ou avec des pourcentages pour
contrôler des instants intermédiaires précis.
Pourcentages pour des animations multi-étapes
@keyframes bounceIn {
0% { transform: scale(0.3); opacity: 0; }
50% { transform: scale(1.05); opacity: 0.8; }
70% { transform: scale(0.9); opacity: 1; }
100% { transform: scale(1); opacity: 1; }
}
Support navigateurs en 2025
| Navigateur | Version min. | Préfixe requis ? | Support |
|---|---|---|---|
| Chrome | 43+ | Non | ✅ Complet |
| Firefox | 16+ | Non | ✅ Complet |
| Safari | 9+ | Non (avant : -webkit-) | ✅ Complet |
| Edge | 12+ | Non | ✅ Complet |
| iOS Safari | 9+ | Non | ✅ Complet |
| Android Chrome | Toutes | Non | ✅ Complet |
-webkit- ne sont plus nécessaires
depuis 2016 pour les animations CSS standards. Vous pouvez les omettre en toute sécurité
dans les projets modernes.
Les types d'animations essentiels
Les animations CSS se regroupent en grandes familles, chacune produisant un effet visuel distinct. Comprendre ces catégories permet de choisir rapidement l'animation la plus adaptée à votre contexte UI.
Fade — Apparition et disparition
Les animations fade jouent sur la propriété opacity.
Elles sont les plus universelles : discrètes, elles conviennent aux éléments de contenu
(modales, tooltips, notifications) sans perturber la mise en page.
/* fadeIn : apparition en douceur */
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
/* fadeInUp : apparition depuis le bas (très courant en landing pages) */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px); /* part 30px plus bas */
}
to {
opacity: 1;
transform: translateY(0); /* arrive à sa position naturelle */
}
}
.hero-title {
animation: fadeInUp 0.7s ease-out both;
}
Slide — Glissement
Les animations slide déplacent l'élément depuis l'extérieur du viewport. Elles sont idéales pour les menus latéraux, les panneaux de navigation et les notifications toast.
/* slideInLeft : entre depuis la gauche */
@keyframes slideInLeft {
from {
transform: translateX(-100%); /* hors de l'écran à gauche */
opacity: 0;
}
to {
transform: translateX(0); /* position normale */
opacity: 1;
}
}
/* Exemple : menu latéral */
.sidebar {
animation: slideInLeft 0.4s ease-out both;
}
Bounce — Effet ressort
Les animations bounce simulent un comportement physique (élasticité, rebond). Elles rendent les interfaces plus vivantes et sont souvent utilisées pour attirer l'attention sur des éléments interactifs (boutons CTA, icônes de notification).
/* bounceIn : apparition avec rebond */
@keyframes bounceIn {
0% { transform: scale(0.3); opacity: 0; }
50% { transform: scale(1.05); } /* dépasse légèrement */
70% { transform: scale(0.9); } /* rebond en arrière */
100% { transform: scale(1); opacity: 1; } /* stabilisation */
}
/* Bouton CTA qui "popppe" à l'apparition */
.cta-button {
animation: bounceIn 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55) both;
}
Spin — Rotation
Les animations de rotation sont indispensables pour les loaders,
les icônes de chargement et les indicateurs d'activité. L'animation rotate360
en boucle infinie est le pattern de spinner le plus répandu sur le web.
/* Loading spinner classique */
@keyframes rotate360 {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
/* Indicateur de chargement */
.spinner {
width: 32px;
height: 32px;
border: 3px solid #e9ecef;
border-top-color: #4f46e5;
border-radius: 50%;
animation: rotate360 0.8s linear infinite;
}
Shake et Wobble — Feedback d'erreur
Les animations shake sont des patterns UX classiques pour signaler une erreur (formulaire invalide, mauvais mot de passe). Elles communiquent un état négatif de manière intuitive sans alerte textuelle supplémentaire.
@keyframes shake {
0%, 100% { transform: translateX(0); }
10%, 30%, 50%, 70%, 90% { transform: translateX(-10px); }
20%, 40%, 60%, 80% { transform: translateX(10px); }
}
/* Appliqué sur un champ de formulaire en erreur */
.input-error {
animation: shake 0.5s ease-in-out;
border-color: #ef4444 !important;
}
Propriétés animation CSS : le guide complet
La propriété raccourcie animation regroupe huit sous-propriétés
distinctes. Les maîtriser permet de créer des effets précis et prévisibles.
| Propriété | Valeurs courantes | Rôle |
|---|---|---|
animation-name |
fadeIn, none |
Nom du @keyframes à utiliser |
animation-duration |
0.3s, 1s, 500ms |
Durée d'un cycle d'animation |
animation-timing-function |
ease, linear, ease-in-out |
Courbe de vitesse (accélération) |
animation-delay |
0s, 0.2s, -1s |
Délai avant le démarrage |
animation-iteration-count |
1, 3, infinite |
Nombre de répétitions |
animation-direction |
normal, reverse, alternate |
Sens de lecture des keyframes |
animation-fill-mode |
none, forwards, both |
Styles avant/après l'animation |
animation-play-state |
running, paused |
Pause/reprise de l'animation |
La propriété animation-timing-function en détail
La timing function contrôle l'accélération de l'animation dans le temps. Elle correspond mathématiquement à une courbe de Bézier cubique.
/* Valeurs prédéfinies */
.element-ease { animation-timing-function: ease; } /* départ rapide, fin lente */
.element-linear { animation-timing-function: linear; } /* vitesse constante */
.element-ease-in { animation-timing-function: ease-in; } /* départ lent */
.element-ease-out { animation-timing-function: ease-out; } /* fin lente */
.element-ease-in-out { animation-timing-function: ease-in-out; } /* doux des deux côtés */
/* Courbe personnalisée avec cubic-bezier */
.element-custom {
animation-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55);
/* Effet élastique : overshoot puis retour */
}
Fill-mode : conserver l'état final
Par défaut, un élément revient à son état CSS d'origine dès que l'animation se termine.
animation-fill-mode: forwards maintient les styles du dernier keyframe —
essentiel pour les animations d'apparition où l'élément doit rester visible.
/* Sans forwards : l'élément disparaît après fadeIn ! */
.sans-fillmode {
opacity: 0; /* état initial CSS */
animation: fadeIn 1s ease;
/* → revient à opacity: 0 après l'animation */
}
/* Avec forwards : l'élément reste visible */
.avec-fillmode {
opacity: 0;
animation: fadeIn 1s ease forwards;
/* → conserve opacity: 1 (état du keyframe to) */
}
Délai négatif pour une animation déjà en cours
/* L'animation démarre 0.5s après sa position */
/* Utile pour décaler des éléments dans une liste */
.item-1 { animation: fadeInUp 0.5s ease both 0.1s; }
.item-2 { animation: fadeInUp 0.5s ease both 0.2s; }
.item-3 { animation: fadeInUp 0.5s ease both 0.3s; }
/* Délai négatif : l'animation semble déjà lancée */
.loader-ring {
animation: rotate360 1.2s linear infinite -0.4s;
/* Commence à 33% de sa progression */
}
Optimisation et performance des animations
Des animations mal optimisées provoquent des jank (saccades), des chutes de FPS et une mauvaise expérience utilisateur. Voici les règles d'or pour des animations fluides à 60 FPS.
Animer uniquement transform et opacity
Le navigateur possède deux mécanismes de rendu : le layout, le paint
et le composite. Les propriétés transform et opacity
sont les seules à ne déclencher que le composite — sans recalcul de
layout ni repaint. Elles sont donc traçables sur GPU et garantissent 60 FPS même sur
appareils modestes.
/* ✅ Performances optimales : GPU composite uniquement */
@keyframes slideRight {
from { transform: translateX(-100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
/* ❌ Performances dégradées : déclenche layout + paint */
@keyframes mauvaisSlide {
from { left: -200px; } /* ← modifie le flux */
to { left: 0; }
}
Propriété will-change : promotion GPU préventive
will-change informe le navigateur en avance qu'une propriété va être
animée, lui permettant de créer un calque GPU dédié à l'élément.
/* Promouvoir l'élément sur GPU AVANT l'animation */
.element-a-animer {
will-change: transform, opacity;
}
/* Important : retirer will-change après l'animation pour libérer la mémoire GPU */
element.addEventListener('animationend', () => {
element.style.willChange = 'auto';
});
will-change à tous les
éléments par défaut — cela consomme de la mémoire GPU. Réservez-le aux éléments
dont l'animation est déclenchée fréquemment (hover, scroll).
Respecter prefers-reduced-motion
La media query prefers-reduced-motion permet de désactiver les animations
pour les utilisateurs sensibles aux mouvements (épilepsie, mal des transports).
C'est une exigence d'accessibilité (WCAG 2.1 — 2.3.3).
/* Animation normale */
.hero {
animation: fadeInUp 0.8s ease both;
}
/* Désactivation pour les utilisateurs sensibles */
@media (prefers-reduced-motion: reduce) {
.hero {
animation: none;
/* Ou remplacer par une transition instantanée */
opacity: 1;
transform: none;
}
}
/* Alternative : réduire la durée plutôt que supprimer */
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
Checklist performance animations
- Utiliser uniquement
transformetopacitydans les keyframes - Éviter d'animer
width,height,top,left,margin - Limiter le nombre d'éléments animés simultanément
- Utiliser
will-changeavec parcimonie sur les éléments à haute fréquence - Implémenter
prefers-reduced-motionsystématiquement - Préférer
animation-fill-mode: bothpour éviter les flashs - Tester sur mobile et appareils peu puissants
Exemples pratiques : loaders, transitions UI
Voici des implémentations concrètes de composants UI courants construits entièrement
en CSS avec des @keyframes.
Loader spinner circulaire
/* Anneau de chargement basique */
@keyframes spin {
to { transform: rotate(360deg); }
}
.loader-ring {
display: inline-block;
width: 40px;
height: 40px;
border: 4px solid rgba(79, 70, 229, 0.15);
border-top-color: #4f46e5;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
/* Variante : trois points pulsants */
@keyframes dotPulse {
0%, 80%, 100% { transform: scale(0); opacity: 0.3; }
40% { transform: scale(1); opacity: 1; }
}
.dot { display: inline-block; width: 8px; height: 8px;
border-radius: 50%; background: #4f46e5;
animation: dotPulse 1.2s infinite ease-in-out both; }
.dot:nth-child(2) { animation-delay: 0.16s; }
.dot:nth-child(3) { animation-delay: 0.32s; }
Barre de progression animée
@keyframes progressFill {
from { width: 0%; }
to { width: var(--target-width, 100%); }
}
.progress-bar {
height: 8px;
background: #e9ecef;
border-radius: 4px;
overflow: hidden;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, #4f46e5, #7c3aed);
border-radius: 4px;
--target-width: 75%;
animation: progressFill 1.5s ease-out forwards;
}
Entrée de liste en cascade
@keyframes listItemIn {
from {
opacity: 0;
transform: translateX(-20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
/* En CSS pur avec nth-child */
.list-item {
animation: listItemIn 0.4s ease-out both;
}
.list-item:nth-child(1) { animation-delay: 0s; }
.list-item:nth-child(2) { animation-delay: 0.08s; }
.list-item:nth-child(3) { animation-delay: 0.16s; }
.list-item:nth-child(4) { animation-delay: 0.24s; }
.list-item:nth-child(5) { animation-delay: 0.32s; }
/* En JavaScript avec des custom properties */
document.querySelectorAll('.list-item').forEach((el, i) => {
el.style.setProperty('--delay', i * 80 + 'ms');
});
/* CSS : animation-delay: var(--delay, 0ms); */
Notification toast avec disparition auto
@keyframes toastIn {
from { transform: translateY(-20px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
@keyframes toastOut {
0% { transform: translateY(0); opacity: 1; }
100% { transform: translateY(-20px); opacity: 0; }
}
.toast {
/* Apparition, pause 2s, disparition */
animation:
toastIn 0.3s ease-out,
toastOut 0.3s ease-in 2.3s forwards;
}
Intégrer les animations dans vos projets
Les animations CSS keyframes fonctionnent dans tout environnement front-end. Voici les patterns d'intégration dans les frameworks JavaScript majeurs.
Angular — déclencher une animation au clic
// app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<div [class.is-animating]="isAnimating"
(animationend)="isAnimating = false">
Contenu animé
</div>
<button (click)="isAnimating = true">Animer</button>
`
})
export class AppComponent {
isAnimating = false;
}
/* app.component.css */
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-20px); }
}
.is-animating {
animation: bounce 0.5s ease;
}
React — déclencher via état
// AnimatedBox.jsx
import { useState } from 'react';
import './AnimatedBox.css';
export function AnimatedBox() {
const [isAnimating, setIsAnimating] = useState(false);
const handleAnimationEnd = () => setIsAnimating(false);
return (
<div>
<div
className={`box ${isAnimating ? 'is-animating' : ''}`}
onAnimationEnd={handleAnimationEnd}
>
Contenu
</div>
<button onClick={() => setIsAnimating(true)}>Animer</button>
</div>
);
}
/* AnimatedBox.css */
@keyframes shake {
0%, 100% { transform: translateX(0); }
25% { transform: translateX(-10px); }
75% { transform: translateX(10px); }
}
.box.is-animating {
animation: shake 0.4s ease;
}
Vue 3 — composant <Transition>
<!-- AnimatedContent.vue -->
<template>
<Transition name="fade-slide">
<div v-if="show" class="content">Contenu</div>
</Transition>
<button @click="show = !show">Toggle</button>
</template>
<style scoped>
/* Vue applique automatiquement ces classes */
.fade-slide-enter-active { animation: fadeInUp 0.4s ease both; }
.fade-slide-leave-active { animation: fadeInUp 0.3s ease both reverse; }
@keyframes fadeInUp {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
</style>
Bibliothèques CSS d'animations prêtes à l'emploi
| Bibliothèque | Poids | Animations | Cas d'usage |
|---|---|---|---|
| Animate.css | ~80 Ko | 80+ effets | Prototypes rapides, sites vitrines |
| GSAP (CSS) | ~30 Ko (core) | Infini via JS | Animations complexes, scroll-driven |
| AOS | ~10 Ko | ~20 effets | Animations au scroll (reveal) |
| Magic CSS | ~36 Ko | 50+ effets | Effets dramatiques, gaming |
FAQ — Animations CSS Keyframes
Quelle différence entre animation et transition CSS ?
Une transition s'applique lors d'un changement d'état (hover, focus,
changement de classe). Elle va d'un état A à un état B. Une animation
avec @keyframes peut définir autant d'étapes intermédiaires que nécessaire,
démarrer automatiquement, boucler et être indépendante d'un changement d'état.
Comment mettre une animation en pause au survol ?
.spinner {
animation: rotate360 1s linear infinite;
}
/* Pause au hover */
.spinner:hover {
animation-play-state: paused;
}
Peut-on appliquer plusieurs animations simultanément ?
Oui, en les séparant par des virgules dans la propriété animation :
.element {
animation:
fadeIn 0.5s ease both,
slideInLeft 0.5s ease both,
pulse 2s ease-in-out 1s infinite;
}
Comment déclencher une animation une seule fois via JavaScript ?
const el = document.querySelector('.mon-element');
function triggerAnimation() {
el.classList.remove('is-animating');
void el.offsetWidth; // Force le reflow pour redémarrer l'animation
el.classList.add('is-animating');
}
el.addEventListener('animationend', () => {
el.classList.remove('is-animating');
});
Pourquoi mon animation ne se relance pas au deuxième déclenchement ?
Si vous ajoutez puis retirez immédiatement une classe, le navigateur optimise en
ne recomposant pas. La solution est de forcer un reflow entre les
deux opérations via element.offsetHeight (lecture d'une propriété
qui force le recalcul du layout).
Les animations CSS fonctionnent-elles sur les pseudo-éléments ?
/* Oui ! Les ::before et ::after sont animables */
.button::after {
content: '';
position: absolute;
background: rgba(255,255,255,0.3);
border-radius: 50%;
animation: ripple 0.6s ease-out;
}
@keyframes ripple {
from { transform: scale(0); opacity: 1; }
to { transform: scale(3); opacity: 0; }
}
Quelle est la durée d'animation recommandée pour l'UX ?
Le Material Design de Google recommande :
- 100-200ms : micro-interactions (hover, focus, boutons)
- 200-400ms : transitions de composants (modales, drawers)
- 400-700ms : transitions de pages, animations expressives
- Au-delà de 1s : réservé aux animations de fond, loaders
Conclusion
Les animations CSS keyframes sont un outil puissant pour enrichir l'expérience utilisateur de vos interfaces. De simples fades aux effets de rebond complexes, tout est possible en CSS pur — sans dépendance JavaScript.
La clé d'une bonne animation UX : discrétion, fluidité et accessibilité.
Concentrez-vous sur transform et opacity, respectez
prefers-reduced-motion, et calibrez les durées pour qu'elles soient
perceptibles sans ralentir l'utilisateur.
Utilisez cet outil pour générer et tester vos keyframes directement dans le navigateur, copiez le CSS généré dans votre feuille de style et appliquez la classe à vos éléments HTML.