Transitions
FondamentauxLes transitions animent le passage d'un état CSS à un autre. Propriété, durée, easing et délai.
transition: property duration timing delayProprié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;
}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;
}@keyframes
FondamentauxLes keyframes définissent des animations complexes multi-étapes. Contrôle total sur chaque pourcentage de l'animation.
from/to ou des pourcentages 0% 50% 100%.animation shorthand :
animation: name duration timing delay count direction fillProprié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;
}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;
}Transforms
Fondamentauxtransform déplace, redimensionne, tourne et déforme les éléments sans affecter le layout. GPU-accelerated.
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);
}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
EffetsLes effets hover donnent du feedback visuel et de la vie à l'interface. Combinez transform, shadow, background et pseudo-éléments.
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; }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
EffetsEffet verre givré avec backdrop-filter: blur() et fond semi-transparent. Tendance UI moderne.
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);
}backdrop-filter
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
EffetsLes gradients CSS peuvent être animés via background-size et background-position. Texte gradient, bordures, etc.
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;
}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.
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%, ...);
}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).
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); }
}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));Micro-animations
AvancéLes détails font la différence. Squelettes de chargement, spinners, indicateurs de statut, transitions de texte.
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 gradient3. 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%; }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;