Développement Web

Comment créer des animations CSS sans JavaScript

11 دقائق للقراءة

Prérequis

  • Niveau : bases HTML/CSS (sélecteurs, propriétés, modèle de boîte).
  • Outils : VS Code + Live Server, navigateur moderne (DevTools → onglet Animations).
  • Temps estimé : 45 min à 1 h.

Pourquoi animer en CSS plutôt qu’en JavaScript ?

Les animations CSS sont déléguées au GPU par le navigateur. Résultat : 60 FPS sans effort, pas de blocage du main thread, et un code beaucoup plus court. Réservez JavaScript aux animations qui dépendent d’une logique complexe ou d’un état applicatif.

Les animations CSS : puissantes et performantes

CSS permet de créer des animations fluides sans écrire une ligne de JavaScript. Plus performantes (gérées par le GPU), elles sont idéales pour les transitions, effets de survol et animations d’apparition.

Transitions : le point de départ

Une transition anime le changement d’une propriété CSS :

/* La transition se déclenche au changement d'état (hover, focus, classe ajoutée...) */
.bouton {
    background: #667eea;
    color: white;
    padding: 12px 30px;
    border: none;
    border-radius: 8px;
    cursor: pointer;
    
    /* transition: propriété durée courbe délai */
    transition: all 0.3s ease;
}

.bouton:hover {
    background: #5a6fd6;
    transform: translateY(-3px);
    box-shadow: 0 8px 25px rgba(102, 126, 234, 0.4);
}

/* Transition sur plusieurs propriétés spécifiques */
.carte {
    transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.carte:hover {
    transform: translateY(-8px);
    box-shadow: 0 15px 35px rgba(0,0,0,0.15);
}

Les courbes d’animation (easing)

Courbe Effet Usage
ease Lent → Rapide → Lent Par défaut, polyvalent
ease-in Démarre lentement Éléments qui disparaissent
ease-out Finit lentement Éléments qui apparaissent
ease-in-out Lent aux deux bouts Mouvements naturels
cubic-bezier() Personnalisé Effets uniques

@keyframes : animations avancées

Voici la mise en pratique pour @keyframes : animations avancées. Le bloc ci-dessous est copiable directement dans votre projet, lisible ligne par ligne. Lisez-le une première fois en survol pour repérer la structure générale, puis adaptez les noms de variables, identifiants et valeurs à votre contexte avant de l’exécuter en local.

/* Définir l'animation */
@keyframes apparition {
    from {
        opacity: 0;
        transform: translateY(30px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* L'appliquer */
.element-anime {
    animation: apparition 0.6s ease-out forwards;
}

/* Animation avec étapes intermédiaires */
@keyframes rebond {
    0%   { transform: translateY(0); }
    25%  { transform: translateY(-20px); }
    50%  { transform: translateY(0); }
    75%  { transform: translateY(-10px); }
    100% { transform: translateY(0); }
}

.icone-rebond {
    animation: rebond 1s ease infinite;
}

Animations pratiques prêtes à l’emploi

Effet de pulsation (bouton CTA)

@keyframes pulse {
    0% { box-shadow: 0 0 0 0 rgba(102, 126, 234, 0.7); }
    70% { box-shadow: 0 0 0 15px rgba(102, 126, 234, 0); }
    100% { box-shadow: 0 0 0 0 rgba(102, 126, 234, 0); }
}

.btn-pulse {
    animation: pulse 2s infinite;
}

Spinner de chargement

@keyframes spin {
    to { transform: rotate(360deg); }
}

.spinner {
    width: 40px;
    height: 40px;
    border: 4px solid #e0e0e0;
    border-top-color: #667eea;
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
}

Texte qui se tape (typewriter)

@keyframes typing {
    from { width: 0; }
    to { width: 100%; }
}

@keyframes blink {
    50% { border-color: transparent; }
}

.typewriter {
    font-family: monospace;
    overflow: hidden;
    white-space: nowrap;
    border-right: 3px solid #667eea;
    width: fit-content;
    animation: 
        typing 3s steps(30) forwards,
        blink 0.7s step-end infinite;
}

Apparition en cascade

@keyframes slideUp {
    from {
        opacity: 0;
        transform: translateY(40px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.carte { 
    animation: slideUp 0.5s ease-out forwards;
    opacity: 0; /* caché par défaut */
}

/* Décalage pour chaque carte */
.carte:nth-child(1) { animation-delay: 0.1s; }
.carte:nth-child(2) { animation-delay: 0.2s; }
.carte:nth-child(3) { animation-delay: 0.3s; }
.carte:nth-child(4) { animation-delay: 0.4s; }

Fond dégradé animé

@keyframes gradient {
    0% { background-position: 0% 50%; }
    50% { background-position: 100% 50%; }
    100% { background-position: 0% 50%; }
}

.hero-anime {
    background: linear-gradient(-45deg, #667eea, #764ba2, #f093fb, #4facfe);
    background-size: 400% 400%;
    animation: gradient 8s ease infinite;
    color: white;
    padding: 100px 40px;
}

Propriétés d’animation

Propriété Valeurs
animation-duration 0.5s, 1s, 2s…
animation-delay 0s, 0.2s, 0.5s…
animation-iteration-count 1, 3, infinite
animation-direction normal, reverse, alternate
animation-fill-mode none, forwards, backwards, both

⚠️ Performance : animez uniquement ces propriétés

Pour des animations fluides à 60 FPS, privilégiez :

  • transform (translate, scale, rotate) — accéléré par le GPU
  • opacity — accéléré par le GPU

Évitez d’animer width, height, margin, padding : elles forcent un recalcul de la mise en page et causent du lag.

Erreurs fréquentes

Animation qui se déclenche puis revient en arrière

Cause : oubli de animation-fill-mode: forwards.
Solution : ajoutez forwards pour que l’élément reste à l’état final.

Animation saccadée (pas 60 FPS)

Cause : on anime width, height, top, left, margin — qui déclenchent un layout à chaque frame.
Solution : animez uniquement transform et opacity. Pour positionner, utilisez translate.

Animation qui ignore les utilisateurs sensibles au mouvement

Cause : aucune media query prefers-reduced-motion.
Solution : enveloppez vos animations : @media (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; } }.

Hover qui « clignote » sur mobile

Cause : :hover reste actif après un tap sur tactile.
Solution : enveloppez avec @media (hover: hover) { ... } pour appliquer le hover uniquement aux pointeurs précis.

Exercice pratique

🎯 Défi : Page d’accueil animée

  1. Hero avec fond dégradé animé et texte typewriter
  2. 3 cartes de services qui apparaissent en cascade au chargement
  3. Boutons avec effet hover (scale + shadow + transition)
  4. Un spinner de chargement
  5. Bonus : ajoutez prefers-reduced-motion pour les utilisateurs sensibles aux animations

@keyframes : animations multi-étapes

Les transitions gèrent un changement A → B. Pour un mouvement qui passe par plusieurs états (un loader qui pulse, un texte qui défile, une icône qui rebondit), il faut @keyframes.

@keyframes pulse {
  0%   { transform: scale(1);   opacity: 1; }
  50%  { transform: scale(1.1); opacity: 0.7; }
  100% { transform: scale(1);   opacity: 1; }
}
.bouton-attention { animation: pulse 2s ease-in-out infinite; }

La syntaxe raccourcie animation regroupe huit propriétés : nom, durée, fonction de timing, délai, nombre d’itérations, direction, fill-mode, état. Pour un loader sur une page de paiement à Dakar, deux secondes par cycle est le sweet spot.

Propriétés performantes : transform et opacity

Animer width, top ou margin déclenche un reflow. Sur un Tecno milieu de gamme à Bamako, c’est la garantie de saccades. À l’inverse, transform et opacity sont gérées par le compositeur GPU sans toucher au layout.

Propriété Coût Verdict
transform: translate / scale / rotate Compositeur GPU Excellent
opacity Compositeur GPU Excellent
filter GPU mais coûteux À doser
width / height / top / left Reflow complet À éviter

will-change : promettre l’animation au navigateur

Voici la mise en pratique pour will-change : promettre l’animation au navigateur. Le bloc ci-dessous est copiable directement dans votre projet, lisible ligne par ligne. Lisez-le une première fois en survol pour repérer la structure générale, puis adaptez les noms de variables, identifiants et valeurs à votre contexte avant de l’exécuter en local.

.carte-produit {
  transition: transform 0.3s ease;
  will-change: transform;
}
.carte-produit:hover { transform: translateY(-4px); }

Bonne pratique : appliquer will-change uniquement sur les éléments réellement animés, puis le retirer. Ne le mettez jamais sur tous les éléments « au cas où ».

Respecter prefers-reduced-motion

Une partie des utilisateurs souffre de troubles vestibulaires. Depuis 2020, la media query prefers-reduced-motion permet de détecter leur préférence système.

@media (prefers-reduced-motion: reduce) {
  .element-anime { animation: none; }
}

Cette media query est désormais obligatoire pour passer un audit Lighthouse Accessibilité au-dessus de 90.

Animations au scroll : scroll-driven animations

Depuis Chrome 115 (juillet 2023) et désormais Safari 26 et Firefox récents, CSS pilote nativement des animations liées au défilement, sans JavaScript ni IntersectionObserver.

.section-revele {
  animation: apparition linear;
  animation-timeline: view();
  animation-range: entry 0% entry 60%;
}

Déboguer les animations dans Chrome DevTools

L’onglet Animations de Chrome DevTools (Ctrl+Shift+P puis taper « Animations ») capture chaque animation déclenchée et permet de la rejouer au ralenti. Cliquez sur la timeline pour modifier la courbe et observer en direct. Pour mesurer les performances réelles, l’onglet Performance avec capture pendant l’animation révèle les frames perdues.

Patterns prêts à l’emploi

Voici la mise en pratique pour Patterns prêts à l’emploi. Le bloc ci-dessous est copiable directement dans votre projet, lisible ligne par ligne. Lisez-le une première fois en survol pour repérer la structure générale, puis adaptez les noms de variables, identifiants et valeurs à votre contexte avant de l’exécuter en local.

@keyframes spin { to { transform: rotate(360deg); } }
.spinner {
  width: 16px; height: 16px;
  border: 2px solid #fff;
  border-top-color: transparent;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

Pour étoffer le tableau sur les patterns frontend modernes adaptés au contexte ouest-africain, voir aussi le guide événements JavaScript et le guide media queries responsive. Tester systématiquement sur Galaxy A03 ou équivalent à 200 EUR avec 4G locale dégradée reste le seul juge fiable de la performance perçue par la majorité des visiteurs locaux.

Pour étoffer le tableau sur les patterns frontend modernes adaptés au contexte ouest-africain, voir aussi le guide événements JavaScript et le guide media queries responsive. Tester systématiquement sur Galaxy A03 ou équivalent à 200 EUR avec 4G locale dégradée reste le seul juge fiable de la performance perçue par la majorité des visiteurs locaux.

Sur un angle proche sur les patterns frontend modernes adaptés au contexte ouest-africain, voir aussi le guide événements JavaScript et le guide media queries responsive. Tester systématiquement sur Galaxy A03 ou équivalent à 200 EUR avec 4G locale dégradée reste le seul juge fiable de la performance perçue par la majorité des visiteurs locaux.

Pour approfondir sur les patterns frontend modernes adaptés au contexte ouest-africain, voir aussi le guide événements JavaScript et le guide media queries responsive. Tester systématiquement sur Galaxy A03 ou équivalent à 200 EUR avec 4G locale dégradée reste le seul juge fiable de la performance perçue par la majorité des visiteurs locaux.

Adaptation au contexte ouest-africain : performance, équipe, marché

Pour un développeur basé à Dakar, Abidjan, Bamako, Cotonou, Lomé, Ouagadougou, Niamey ou Conakry qui livre des sites web ou applications custom à des PME locales, trois adaptations pèsent sur le succès des projets. Premièrement, la connectivité 4G inégale impose de réduire le poids des pages au strict nécessaire — un site qui charge en 6 secondes perd 40 % de ses visiteurs avant l’affichage. Deuxièmement, le profil typique des développeurs disponibles sur le marché local est majoritairement formé sur du JavaScript moderne et du PHP, avec une expertise variable sur les outils plus avancés (TypeScript, frameworks edge, design systems). Adapter la pile technique au profil d’équipe disponible sur place évite la dette technique liée au turn-over.

Troisièmement, le coût en FCFA des services cloud doit être anticipé dans le budget. Hetzner CX22 à 4 500 FCFA/mois reste imbattable pour un démarrage, Cloudflare Pages gratuit pour les sites statiques, Backblaze B2 à 6 USD/TB/mois pour les sauvegardes. Pour les projets B2C qui exigent une latence faible, héberger sur un CDN avec PoP africain (Cloudflare Lagos, Africa Data Centres) divise par trois la latence perçue par rapport à un déploiement européen sans CDN.

Tester sur appareils réels avant la mise en production

Plus important que tous les outils synthétiques, tester son site sur un Android d’entrée de gamme avec une connexion 4G locale dégradée donne le seul verdict qui compte. Galaxy A03 à 200 EUR neuf, Tecno Spark, Itel A60 sont les appareils dominants chez les visiteurs ouest-africains. Sur ces téléphones, un site qui semble rapide sur DevTools peut être laggy en réalité. Trois conseils pratiques. Premièrement, garder un appareil de test physique à portée de main pour vérifier chaque livraison majeure. Deuxièmement, profiler avec Chrome DevTools en mode Slow 4G + 4x CPU slowdown pour simuler ces conditions. Troisièmement, mesurer en conditions réelles avec PageSpeed Insights qui agrège les données du Chrome User Experience Report sur 28 jours — la donnée terrain qui compte vraiment.

Erreurs courantes en développement web à éviter

Trois patterns reviennent dans les projets web mal exécutés et coûtent cher à corriger plus tard. Premier pattern : copier-coller de code Stack Overflow sans comprendre le contexte d’origine. Une solution qui marche pour un cas particulier devient un bug subtil dans un autre — toujours adapter au contexte de votre projet. Deuxième pattern : ignorer les warnings de la console. Chaque warning est un signal qui mérite d’être lu et compris. Une console pleine de warnings finit par cacher les vrais problèmes. Troisième pattern : ne pas tester sur de vrais appareils. DevTools simule mais ne remplace pas un test physique sur un Android d’entrée de gamme avec une 4G dégradée — c’est le contexte réel d’usage de la majorité des visiteurs locaux.

Pour approfondir sur les bonnes pratiques de développement web modernes adaptées au contexte ouest-africain, voir aussi le guide responsive design et le guide Bootstrap 5. Documenter chaque décision technique majeure dans un fichier ADR (Architecture Decision Record) prend dix minutes et fait gagner des heures lors d’un incident ou d’un audit.

Sur un angle proche

مشاركة