🎨 Animations CSS
← Retour au cours
🎨

Maîtriser les Animations CSS

Transitions, keyframes, transforms, effets hover, glassmorphism, scroll animations. Guide interactif avec démos live.

9Sections
18Concepts
18Démos live

💫 Transitions

Fondamentaux

Les transitions animent le passage d'un état CSS à un autre. Propriété, durée, easing et délai.

CSStransition shorthandPropriété, durée, timing, délai
Syntaxe : transition: property duration timing delay

Propriétés : all, transform, opacity, background, color...

Timing : ease (défaut), linear, ease-in, ease-out, ease-in-out, ou cubic-bezier() custom.

Astuce : cubic-bezier(.4,0,.2,1) est le easing Material Design — fluide et pro.

Performance : Animez uniquement transform et opacity — ils utilisent le GPU (composite layer).
.button {
  background: #ff6b35;
  transform: scale(1);
  opacity: 1;
  transition: all 0.4s cubic-bezier(.4,0,.2,1);
}

.button:hover {
  background: #a78bfa;
  transform: scale(1.1) rotate(5deg);
  border-radius: 50%;
  box-shadow: 0 0 30px rgba(167,139,250,.4);
}

/* Transitions multiples */
.card {
  transition:
    transform 0.3s ease,
    box-shadow 0.3s ease 0.05s,
    border-color 0.2s ease;
}
▶ Hover moi
Hover
CSScubic-bezier & easingCourbes d'accélération custom
cubic-bezier(x1,y1,x2,y2) : Contrôle la courbe de vitesse. Les 2 points définissent les handles de Bézier.

Presets populaires :
ease = cubic-bezier(.25,.1,.25,1)
• Bounce : cubic-bezier(.68,-.55,.27,1.55)
• Snap : cubic-bezier(0,.9,.1,1)

steps() : Animation par paliers discrets. Utile pour les sprites et machines à écrire.

Outil : cubic-bezier.com pour visualiser.
/* Bounce overshoot */
.bounce {
  transition: transform 0.5s
    cubic-bezier(.68, -.55, .27, 1.55);
}
.bounce:hover { transform: scale(1.2); }

/* Elastic snap */
.snap {
  transition: transform 0.3s
    cubic-bezier(0, .9, .1, 1);
}

/* Steps — sprite animation */
.sprite {
  background: url('sprite.png');
  width: 64px; height: 64px;
  animation: walk 0.6s steps(8) infinite;
}
@keyframes walk {
  to { background-position: -512px 0; }
}

/* Steps — typewriter */
.typewriter {
  overflow: hidden;
  white-space: nowrap;
  border-right: 2px solid;
  animation:
    typing 3s steps(30) infinite,
    blink 0.6s step-end infinite alternate;
}
Typing effect
console.log("CSS");

🎬 @keyframes

Fondamentaux

Les keyframes définissent des animations complexes multi-étapes. Contrôle total sur chaque pourcentage de l'animation.

Anim@keyframes & animationDéfinir et appliquer des animations
@keyframes nom : Définit les étapes. Utilisez from/to ou des pourcentages 0% 50% 100%.

animation shorthand : animation: name duration timing delay count direction fill

Propriétés clés :
iteration-count : infinite ou un nombre
direction : normal, reverse, alternate
fill-mode : forwards garde l'état final
play-state : paused / running
@keyframes bounce {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-25px); }
}

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

@keyframes pulse {
  0%, 100% { transform: scale(1); opacity: 1; }
  50%      { transform: scale(1.3); opacity: 0.5; }
}

.ball    { animation: bounce 1s ease infinite; }
.loader  { animation: spin 1s linear infinite; }
.dot     { animation: pulse 1.5s ease-in-out infinite; }

/* Pause on hover */
.animated:hover {
  animation-play-state: paused;
}
Live
AnimAnimation multi-étapesPourcentages, délais, chaînage
Pourcentages : Contrôlez chaque moment. 0% = début, 100% = fin, n'importe quel % entre les deux.

Animations multiples : Séparez par virgule pour combiner plusieurs animations.

animation-delay négatif : Démarre l'animation à mi-parcours — utile pour des stagger effects.

Stagger : Appliquez des délais croissants à chaque élément pour un effet cascade.
@keyframes slideUp {
  0%   { opacity: 0; transform: translateY(30px); }
  100% { opacity: 1; transform: translateY(0); }
}

/* Stagger avec délais */
.item:nth-child(1) { animation-delay: 0s; }
.item:nth-child(2) { animation-delay: 0.1s; }
.item:nth-child(3) { animation-delay: 0.2s; }
.item:nth-child(4) { animation-delay: 0.3s; }

.item {
  animation: slideUp 0.6s ease both;
}

/* Combiner plusieurs animations */
.fancy {
  animation:
    spin 2s linear infinite,
    pulse 1s ease-in-out infinite;
}
Cliquer pour relancer
🟦
🟪
🟧
🟥

🔄 Transforms

Fondamentaux

transform déplace, redimensionne, tourne et déforme les éléments sans affecter le layout. GPU-accelerated.

CSStranslate, scale, rotate, skewLes 4 transformations de base
translate(x, y) : Déplace l'élément sans toucher au flow.
scale(x, y) : Agrandit/rétrécit. scale(1.5) = 150%.
rotate(angle) : Tourne. En deg, turn ou rad.
skew(x, y) : Déforme en parallélogramme.

Combinaison : transform: translateY(-10px) scale(1.1) rotate(5deg)

transform-origin : Définit le point de pivot. Défaut : center. Peut être top left, 50% 100%, etc.
/* Translate */
.move { transform: translate(20px, -10px); }
.moveX { transform: translateX(50%); }

/* Scale */
.grow { transform: scale(1.2); }
.shrink { transform: scale(0.8); }

/* Rotate */
.tilt { transform: rotate(12deg); }
.flip { transform: rotateY(180deg); }

/* Skew */
.slant { transform: skewX(-8deg); }

/* Combine */
.card:hover {
  transform:
    translateY(-8px)
    scale(1.02)
    rotate(1deg);
}

/* Origin */
.corner-rotate {
  transform-origin: top left;
  transform: rotate(45deg);
}
Hover chaque
Rotate
Scale
Skew
Move
CSS3D Transforms & PerspectiverotateX/Y, perspective, preserve-3d
perspective : Définit la profondeur 3D. Plus la valeur est petite, plus l'effet est prononcé. perspective: 800px est un bon défaut.

rotateX/Y : Tourne autour des axes X (horizontal) et Y (vertical).

transform-style: preserve-3d : Les enfants gardent leur positionnement 3D — essentiel pour les effets de flip card.

backface-visibility: hidden : Cache la face arrière lors d'une rotation 3D.
/* Perspective container */
.scene {
  perspective: 800px;
}

/* Flip card */
.flip-card {
  position: relative;
  transform-style: preserve-3d;
  transition: transform 0.6s ease;
}
.flip-card:hover {
  transform: rotateY(180deg);
}
.front, .back {
  position: absolute;
  backface-visibility: hidden;
}
.back { transform: rotateY(180deg); }

/* Tilt on hover */
.tilt-card:hover {
  transform:
    perspective(800px)
    rotateX(5deg)
    rotateY(-5deg)
    scale(1.02);
}

🖱 Hover Effects

Effets

Les effets hover donnent du feedback visuel et de la vie à l'interface. Combinez transform, shadow, background et pseudo-éléments.

EffectCard lift & glowElévation, ombre, bordure luminescente
Pattern card lift : translateY(-6px) + box-shadow accru au hover. Donne une sensation de profondeur physique.

Glow border : border-color + box-shadow coloré pour un effet néon.

::before overlay : Un pseudo-élément avec gradient qui apparaît au hover — effet de surbrillance subtil.

Astuce : Utilisez will-change: transform pour prévenir le navigateur et optimiser.
.card {
  background: rgba(255,255,255,0.03);
  border: 1px solid rgba(255,255,255,0.07);
  border-radius: 12px;
  padding: 20px;
  transition: all 0.3s cubic-bezier(.4,0,.2,1);
  position: relative;
  overflow: hidden;
}

.card::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    135deg,
    rgba(255,107,53,0.08),
    rgba(167,139,250,0.08)
  );
  opacity: 0;
  transition: opacity 0.3s;
}

.card:hover {
  transform: translateY(-6px);
  border-color: rgba(255,107,53,0.3);
  box-shadow: 0 12px 40px rgba(0,0,0,0.25);
}
.card:hover::before { opacity: 1; }
Hover
🚀Card Lift
Glow Effect
EffectBoutons animésRipple, slide, morph
Scale + shadow : Le plus simple. transform: scale(1.05) + shadow accru.

Background slide : Un ::before avec translateX(-100%) qui slide au hover via translateX(0).

Active state : :active { transform: scale(0.97) } pour le feedback au clic.

Focus visible : :focus-visible pour les outlines accessibles uniquement au clavier.
/* Scale + glow */
.btn {
  padding: 10px 24px;
  background: linear-gradient(135deg, #ff6b35, #a78bfa);
  border: none; border-radius: 8px;
  color: #fff; font-weight: 700;
  transition: all 0.2s ease;
}
.btn:hover {
  transform: translateY(-2px) scale(1.02);
  box-shadow: 0 8px 24px rgba(255,107,53,0.3);
}
.btn:active { transform: scale(0.97); }

/* Slide background */
.btn-slide {
  position: relative;
  overflow: hidden;
  z-index: 1;
}
.btn-slide::before {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(255,255,255,0.15);
  transform: translateX(-100%);
  transition: transform 0.3s ease;
  z-index: -1;
}
.btn-slide:hover::before {
  transform: translateX(0);
}

Glassmorphism

Effets

Effet verre givré avec backdrop-filter: blur() et fond semi-transparent. Tendance UI moderne.

EffectGlass Cardbackdrop-filter, rgba, border subtile
Recette :
1. background: rgba(255,255,255, 0.05-0.15)
2. backdrop-filter: blur(12-20px)
3. border: 1px solid rgba(255,255,255, 0.1-0.2)
4. Fond coloré derrière pour que le blur soit visible

Support : Tous les navigateurs modernes. Fallback : augmenter l'opacité du background.

Performance : backdrop-filter est GPU-accelerated mais coûteux. Évitez sur trop d'éléments simultanés.
.glass-card {
  background: rgba(255, 255, 255, 0.08);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 16px;
  padding: 24px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
}

/* Variante sombre */
.glass-dark {
  background: rgba(0, 0, 0, 0.3);
  backdrop-filter: blur(20px) saturate(1.5);
  border: 1px solid rgba(255, 255, 255, 0.08);
}

/* Topbar glassmorphism */
.topbar {
  background: rgba(10, 10, 18, 0.85);
  backdrop-filter: blur(16px);
  border-bottom: 1px solid rgba(255,255,255,0.07);
}
Live
Glass Card
backdrop-filter
EffectNeumorphism & Soft UIOmbres intérieures/extérieures, relief
Neumorphism : Double ombre (claire en haut-gauche, sombre en bas-droit) créant un effet de relief.

Inset : box-shadow: inset ... pour un effet enfoncé.

Limites : Nécessite un fond uni. Mauvaise accessibilité (faible contraste). À utiliser avec modération.
/* Neumorphism — relief */
.neumorph {
  background: #1a1a2e;
  border-radius: 16px;
  box-shadow:
    6px 6px 16px rgba(0, 0, 0, 0.5),
    -6px -6px 16px rgba(255, 255, 255, 0.03);
}

/* Pressed / Inset */
.neumorph-pressed {
  box-shadow:
    inset 4px 4px 12px rgba(0, 0, 0, 0.5),
    inset -4px -4px 12px rgba(255, 255, 255, 0.02);
}

/* Soft glow */
.soft-glow {
  box-shadow:
    0 0 20px rgba(0, 210, 255, 0.15),
    0 0 60px rgba(0, 210, 255, 0.05);
}

🌈 Gradients animés

Effets

Les gradients CSS peuvent être animés via background-size et background-position. Texte gradient, bordures, etc.

EffectGradient text & shiftTexte gradient animé, background shifting
Texte gradient : background-clip: text + -webkit-text-fill-color: transparent. Le gradient devient la couleur du texte.

Animation : Utilisez background-size: 200% et animez background-position pour un effet de défilement.

Gradient border : Impossible nativement. Trick : border-image ou pseudo-élément sous la card avec un gradient plus large.
/* Gradient text */
.gradient-text {
  background: linear-gradient(
    90deg, #ff6b35, #f472b6, #a78bfa, #00d2ff
  );
  background-size: 200% auto;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: gradientShift 3s linear infinite;
}

@keyframes gradientShift {
  to { background-position: 200% center; }
}

/* Gradient border */
.gradient-border {
  position: relative;
  background: #0a0a12;
  border-radius: 12px;
}
.gradient-border::before {
  content: '';
  position: absolute;
  inset: -1px;
  background: linear-gradient(135deg, #ff6b35, #a78bfa);
  border-radius: inherit;
  z-index: -1;
}
Live
Gradient Animé
EffectConic & radial gradientsGradients circulaires et coniques
radial-gradient : Gradient circulaire. Parfait pour les spots de lumière, vignettes, glow effects.

conic-gradient : Gradient angulaire (comme une roue). Utile pour les charts circulaires CSS-only.

repeating-*-gradient : Répète le pattern — rayures, grilles, motifs géométriques.
/* Spot light effect */
.spotlight {
  background: radial-gradient(
    circle at 30% 40%,
    rgba(0, 210, 255, 0.15),
    transparent 60%
  );
}

/* Pie chart CSS only */
.pie {
  width: 100px; height: 100px;
  border-radius: 50%;
  background: conic-gradient(
    #ff6b35 0% 35%,
    #a78bfa 35% 65%,
    #00d2ff 65% 100%
  );
}

/* Repeating stripes */
.stripes {
  background: repeating-linear-gradient(
    45deg,
    transparent,
    transparent 10px,
    rgba(255,255,255,0.03) 10px,
    rgba(255,255,255,0.03) 20px
  );
}

Clip-path

Avancé

clip-path découpe un élément selon une forme. Animable pour des transitions de forme spectaculaires.

CSSFormes clip-pathcircle, polygon, inset, path
circle(radius) : Découpe en cercle.
polygon(points) : Forme libre. Chaque point = x% y%.
inset(top right bottom left round r) : Rectangle avec border-radius.

Animation : clip-path est animable ! Transitions fluides entre formes.

Outil : Clippy (bennettfeely.com/clippy) pour générer les polygon.
/* Circle reveal */
.reveal {
  clip-path: circle(0% at 50% 50%);
  transition: clip-path 0.6s ease;
}
.reveal:hover {
  clip-path: circle(100% at 50% 50%);
}

/* Shapes */
.pentagon {
  clip-path: polygon(
    50% 0%, 100% 38%, 82% 100%,
    18% 100%, 0% 38%
  );
}

.star {
  clip-path: polygon(
    50% 0%, 61% 35%, 98% 35%,
    68% 57%, 79% 91%, 50% 70%,
    21% 91%, 32% 57%, 2% 35%, 39% 35%
  );
}

/* Transition between shapes */
.morph {
  clip-path: circle(50%);
  transition: clip-path 0.5s ease;
}
.morph:hover {
  clip-path: polygon(50% 0%, 100% 38%, ...);
}
Hover pour changer
CSSMasks & blend modesmask-image, mix-blend-mode, isolation
mask-image : Comme clip-path mais avec un gradient. Utile pour des fades progressifs.

mix-blend-mode : Fusionne un élément avec son fond. multiply, screen, overlay, difference.

isolation: isolate : Crée un nouveau contexte de stacking pour limiter le blend mode aux enfants.
/* Gradient fade mask */
.fade-bottom {
  -webkit-mask-image: linear-gradient(
    to bottom, black 60%, transparent
  );
  mask-image: linear-gradient(
    to bottom, black 60%, transparent
  );
}

/* Blend mode */
.overlay-text {
  mix-blend-mode: difference;
  color: white;
  font-size: 4rem;
}

/* Isolated blend */
.blend-container {
  isolation: isolate;
}
.blend-container .layer {
  mix-blend-mode: screen;
}

📜 Scroll Effects

Avancé

Animations déclenchées par le scroll. scroll-driven animations (CSS natif) et IntersectionObserver (JS).

AnimScroll-driven CSSanimation-timeline, view(), scroll()
scroll() (Chrome 115+) : Lie une animation au défilement de la page. Plus besoin de JS !

view() : Lie l'animation à la visibilité de l'élément dans le viewport.

animation-timeline : Remplace le temps par la position du scroll.

Support : Chrome/Edge 115+. Fallback : IntersectionObserver.
/* Progress bar liée au scroll */
.progress-bar {
  position: fixed;
  top: 0; left: 0;
  height: 3px;
  background: linear-gradient(90deg, #ff6b35, #a78bfa);
  transform-origin: left;
  animation: scaleX linear;
  animation-timeline: scroll();
}
@keyframes scaleX {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

/* Reveal on scroll */
.reveal-on-scroll {
  animation: fadeSlideUp linear both;
  animation-timeline: view();
  animation-range: entry 0% entry 100%;
}
@keyframes fadeSlideUp {
  from { opacity: 0; transform: translateY(40px); }
  to   { opacity: 1; transform: translateY(0); }
}
AnimIntersectionObserverReveal avec JS fallback universel
IntersectionObserver : API JS qui détecte quand un élément entre dans le viewport. Support universel.

Pattern : Éléments avec opacity: 0; transform: translateY(20px) par défaut. L'observer ajoute .visible au scroll.

Stagger : Combinez avec transition-delay sur chaque enfant pour un effet cascade.
/* CSS */
.scroll-item {
  opacity: 0;
  transform: translateY(30px);
  transition: all 0.6s ease;
}
.scroll-item.visible {
  opacity: 1;
  transform: translateY(0);
}
/* Stagger */
.scroll-item:nth-child(2) { transition-delay: .1s; }
.scroll-item:nth-child(3) { transition-delay: .2s; }

/* JavaScript */
const observer = new IntersectionObserver(
  (entries) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        entry.target.classList.add('visible');
      }
    });
  },
  { threshold: 0.1 }
);

document.querySelectorAll('.scroll-item')
  .forEach(el => observer.observe(el));
Cliquer pour relancer
🟦
🟪
🟧
🟥

Micro-animations

Avancé

Les détails font la différence. Squelettes de chargement, spinners, indicateurs de statut, transitions de texte.

EffectSkeleton loadingShimmer effect, placeholder animé
Skeleton : Placeholder animé pendant le chargement. Meilleur UX que les spinners car il montre la structure du contenu à venir.

Shimmer : Gradient linéaire 200% wide qui se déplace de droite à gauche — effet de reflet.

Recette :
1. Formes grises (rectangles, cercles) qui imitent le contenu
2. background-size: 200% avec gradient
3. Animation background-position
.skeleton-line {
  height: 12px;
  border-radius: 6px;
  background: linear-gradient(
    90deg,
    rgba(255,255,255,0.06) 25%,
    rgba(255,255,255,0.03) 50%,
    rgba(255,255,255,0.06) 75%
  );
  background-size: 200% 100%;
  animation: shimmer 1.5s ease-in-out infinite;
}

@keyframes shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* Skeleton card */
.skeleton-card {
  padding: 16px;
}
.skeleton-card .avatar {
  width: 40px; height: 40px;
  border-radius: 50%;
}
.skeleton-card .line { margin-top: 8px; }
.skeleton-card .line:nth-child(2) { width: 60%; }
.skeleton-card .line:nth-child(3) { width: 80%; }
Live
Effectprefers-reduced-motionAccessibilité et respect des préférences
@media (prefers-reduced-motion: reduce) : Détection des utilisateurs qui préfèrent réduire les animations (paramètre OS).

Bonne pratique : Toujours fournir un fallback sans animation. Désactivez les animations non-essentielles, gardez les transitions de base (opacity, color).

Astuce : Placez cette media query à la fin de votre CSS pour qu'elle override tout.
/* Désactiver les animations */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Alternative : garder les transitions simples */
@media (prefers-reduced-motion: reduce) {
  .card {
    transition: opacity 0.2s ease;
    /* Pas de transform, pas de bounce */
  }
  .loader {
    animation: none;
    /* Remplacer par texte "Chargement..." */
  }
}

/* Check en JS */
const prefersReduced = window.matchMedia(
  '(prefers-reduced-motion: reduce)'
).matches;