Weight Breathing
Animation CSS pure : font-weight oscille entre 300 et 900 avec letter-spacing compensé — le texte respire sans une ligne de JavaScript.
Cet effet est gratuit — la catégorie Texte en contient 56 au total, dont 4 gratuits. Effect.Labs regroupe 811 effets vanilla. Découvrir la catégorie →
Exemples d'usage
Comment ça marche
L'effet repose sur un @keyframes vfBreathe qui interpole simultanément font-weight (300 → 900 → 300) et letter-spacing (2px → -1px → 2px) en 3 secondes. La courbe ease-in-out produit une accélération douce au milieu de l'oscillation — c'est ce rythme qui évoque une respiration plutôt qu'un clignotement mécanique.
L'interpolation fluide de font-weight n'est possible qu'avec une police variable (axe wght continu) : avec Inter, Roboto Flex ou toute fonte variable, la graisse passe de façon analogique de 300 à 900. Avec une fonte statique classique, le navigateur saute entre les graisses disponibles — souvent seulement 400 et 700.
Le letter-spacing est animé simultanément pour compenser l'expansion optique : une graisse très lourde occupe davantage d'espace horizontal, et ramener le crénage à -1px à l'apex stabilise visuellement la largeur du mot. Sans cet ajustement, le texte semblerait « pousser » ses voisins à chaque cycle.
L'effet est 100 % CSS — aucun requestAnimationFrame, aucune dépendance JS. Un seul <span class="vf-breathing-text"> et la règle @keyframes suffisent : le navigateur délègue entièrement l'interpolation à son moteur de rendu.
Accessibilité
- prefers-reduced-motion absent : le code fourni ne contient pas de bloc
@media (prefers-reduced-motion: reduce). Pour respecter les préférences de l'OS, ajoutez :@media (prefers-reduced-motion:reduce){.vf-breathing-text{animation:none;font-weight:600}}. - Le texte animé est un
<span>inline standard — lisible normalement par les lecteurs d'écran, sansaria-hiddenqui le masquerait. - Contraste : texte blanc
rgb(255,255,255)sur fondrgb(10,10,15)— ratio > 19:1, largement supérieur au seuil WCAG AA (4,5:1). - Aucune interaction clavier ni focus requis — l'effet est purement décoratif et ne génère aucun piège de focus.
- Pas de contenu qui clignote à plus de 3 Hz : le cycle de 3 s est très en dessous du seuil de risque épileptique défini par WCAG 2.3.1.
Compatibilité navigateur
L'animation CSS est supportée partout depuis IE 10 ; l'interpolation fluide de font-weight exige une police variable avec axe wght.
Sans police variable, <code>font-weight</code> se cale sur les graisses statiques disponibles (souvent 400/700) — l'animation reste fonctionnelle mais saute par paliers au lieu d'être analogique.
Le code
Copiez les trois blocs dans votre page. Aucune dépendance.
<div class="vf-preview" style="width:100%;min-height:300px;">
<div class="vf-breathing-scene">
<span class="vf-breathing-text">Breathe</span>
<span class="vf-breathing-sub">font-weight: 300 ↔ 900</span>
</div>
</div>
.vf-breathing-scene {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 16px;
}
.vf-breathing-text {
font-family: Inter, sans-serif;
font-size: 2.5rem;
color: rgb(255, 255, 255);
animation: 3s ease-in-out 0s infinite normal none running vfBreathe;
}
.vf-breathing-sub {
font-size: 0.75rem;
color: rgba(255, 255, 255, 0.4);
}
@keyframes vfBreathe {
0%, 100% {
font-weight: 300;
letter-spacing: 2px;
}
50% {
font-weight: 900;
letter-spacing: -1px;
}
}
// Effet CSS pur — pas de JavaScript nécessaire
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
| animation-duration: 3s | 3s | Vitesse du cycle de respiration. 2 s = rapide, 5 s = méditatif. Modifiez la valeur dans le sélecteur .vf-breathing-text. |
| font-weight 300 → 900 | 300 / 900 | Plage de graisse dans @keyframes vfBreathe (à 0%/100% et 50%). Réduisez à 400→700 pour une oscillation plus subtile. |
| letter-spacing 2px → -1px | 2px / -1px | Compensation de crénage dans @keyframes vfBreathe. Ajustez si votre fonte a un comportement optique différent. |
| font-family: Inter | Inter, sans-serif | Remplacez par toute police variable avec axe wght (Roboto Flex, Manrope, Cabinet Grotesk…). Sans variable font, l'animation sera saccadée. |
| font-size: 2.5rem | 2.5rem | Taille du texte dans .vf-breathing-text. L'effet est plus saisissant à partir de 3 rem. |
| animation-timing-function | ease-in-out | Courbe de cycle. cubic-bezier(0.4,0,0.2,1) = Material ; linear = oscillation mécanique régulière. |
| color: rgb(255,255,255) | blanc | Couleur dans .vf-breathing-text. Compatible avec background-clip:text pour animer un dégradé en même temps que la graisse. |
FAQ
L'animation est saccadée — pourquoi ?
L'interpolation fluide de font-weight exige une police variable avec axe wght continu. Avec une fonte statique classique, le navigateur saute entre les graisses disponibles (souvent 400 et 700). Passez à Inter Variable, Roboto Flex ou toute autre variable font pour une transition analogique de 300 à 900.
Comment appliquer l'effet à plusieurs textes avec des décalages différents ?
Ajoutez animation-delay sur chaque .vf-breathing-text. Un délai négatif (ex. -1.5s) démarre le second élément au milieu du cycle, créant un effet de vague : le premier est léger quand le second est lourd. Un délai négatif est immédiat et évite un flash initial à font-weight 300.
Comment respecter prefers-reduced-motion ?
Le code fourni n'inclut pas ce media query. Ajoutez après les règles de l'effet : @media (prefers-reduced-motion:reduce){.vf-breathing-text{animation:none;font-weight:600}}. Cela fige le texte à une graisse intermédiaire lisible sans le faire disparaître.