Rotating Text
Un mot en dégradé indigo → magenta, sans boîte autour, oscille doucement en 3D (±15° autour de l'axe vertical, ±10° autour de l'horizontal, boucle de 4 s) et fait un tour complet sur lui-même en 1 s quand on le survole ou qu'il reçoit le focus clavier. CSS pur, zéro JavaScript, de face et immobile si l'utilisateur réduit les animations.
Mis à jour le
Cet effet fait partie d'Effect.Labs — 840 effets vanilla, une partie gratuite, une partie premium. 3D comprend 50 effets, dont 8 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
La racine .fx-0008-root (fond #0a0a0f, 300 px de haut au minimum) centre .text-rotate-container, qui porte la caméra (perspective: 400px, courte, pour que 15° se voient sur un mot) et tabindex="0". Dedans, .text-rotate (28 px, graisse 800, transform-style: preserve-3d) joue textRotate3D : 4 s, ease-in-out, sans fin ; à 0, 50 et 100 % le mot est de face, à 25 % il tourne de 15° vers la droite et bascule de 10° vers l'arrière, à 75 % l'inverse. Le résultat est un balancement en huit, lent, comme un panneau suspendu. Le texte lui-même est un <span> en inline-block dont le fond est un dégradé #6366f1 → #d946ef à 135°, découpé à la forme des lettres (background-clip: text, avec sa version -webkit-) et rendu visible par -webkit-text-fill-color: transparent.
Le tour complet est une seconde animation, textSpin (rotateY(0) → rotateY(360deg), 1 s, une seule fois), qui remplace le balancement quand .text-rotate-container est survolé ou a le focus clavier (:focus-visible, contour de 2 px #a5b4fc). Le tour fini, le mot reste de face tant que le pointeur est dessus ; il reprend son balancement en partant. Le survol est lu sur le conteneur, qui ne tourne pas, et non sur le mot : vu de profil en plein tour, le mot n'a presque plus de surface, et un survol lu sur lui se perdrait. Mesuré dans Chromium 151 et Firefox 153, pointeur posé près du bord du mot et bougeant de 3 px : sur le conteneur, le tour va au bout ; un survol lu sur le mot lui-même fait repartir le tour de zéro toutes les 0,35 s environ.
Le balancement ne déplace qu'un mot : 0,44 % des pixels du bloc changent en 0,8 s, l'effet reste discret. Seul transform est animé. Deux copies sur une page se balancent et tournent chacune de leur côté. Le dégradé découpé au texte ne dépend pas de la 3D ; la rotation, si : le WebKit de Playwright aplatit toute 3D CSS, le rendu sur un vrai Safari n'a pas été vérifié.
Accessibilité
- Mouvement réduit : sous
prefers-reduced-motion: reduce, un bloc limité à.fx-0008-rootretire le balancement et le tour : le mot reste de face. Au survol et au focus, il s'éclaircit (filter: brightness(1.35)) au lieu de tourner. Mesuré dans Chromium et Firefox : 0 animation en cours, 0 % des pixels qui changent en 0,8 s, aucune animation au survol. - Lisibilité : c'est du vrai texte, lu tel quel par les lecteurs d'écran et sélectionnable. Le dégradé va de 4,4:1 (indigo) à 5,7:1 (magenta) sur le fond
#0a0a0f, au-dessus du seuil de 3:1 pour un texte de 28 px gras. Pendant le tour, le mot est illisible une demi-seconde : ne l'utilisez pas pour une information qu'on doit lire au moment du survol. - Clavier : le conteneur a
tabindex="0", le tour part au focus clavier avec un contour visible. Si le mot est un lien, retirez cetabindexet visez le lien (a:focus-visible .text-rotate) : un élément focalisable qui ne fait rien ajoute un arrêt inutile au parcours clavier. - Toucher : sur téléphone, un appui sur le mot déclenche le survol émulé par le navigateur, donc un tour ; le balancement, lui, tourne sans geste.
Compatibilité navigateur
CSS (transform 3D, perspective, background-clip: text, -webkit-text-fill-color, @keyframes), zéro JavaScript, aucune dépendance. Mesuré dans Chromium 151 et Firefox 153 : même balancement (0,68 % d'écart sur l'image fixe, dû au lissage du texte), tour complet au survol et au focus, deux copies indépendantes, 0 erreur. Le WebKit de Playwright 26.5 aplatit toute 3D CSS : le vrai Safari n'a pas été vérifié.
Sans 3D CSS, le mot reste à plat et le balancement se réduit à un léger étirement horizontal. Sans background-clip: text, la propriété -webkit-text-fill-color est en général ignorée elle aussi et le mot s'affiche dans la couleur du texte (blanc), sans dégradé.
Le code
Structure HTML à coller dans votre page (le CSS + JS sont inclus avec votre achat) :
<div class="fx-0008-root">
<div class="demo-3d">
<div class="text-rotate-container" tabindex="0">
<div class="text-rotate">
<span>3D TEXT</span>
</div>
</div>
</div>
</div>
Paiement unique, sans abonnement — le code est à toi pour toujours
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
Amplitude du balancement (CSS — @keyframes textRotate3D, étapes 25 % et 75 %) |
rotateY ±15°, rotateX ±10° | ±8° / ±5° pour un mot qui respire à peine ; ±25° / ±15° pour un panneau battu par le vent. Gardez 0 % = 50 % = 100 % de face : la boucle passe par le repos deux fois. |
Durée du balancement (CSS — 4s dans l'animation de .text-rotate) |
4 s, ease-in-out | 6 s pour une enseigne lourde, 2,5 s pour un effet plus nerveux. ease-in-out marque un ralenti aux extrémités, comme un objet suspendu. |
Perspective (CSS — perspective de .text-rotate-container) |
400px | Courte, elle rend visibles de petits angles. 800 px aplatit le balancement ; 250 px le rend très marqué, au risque de déformer les longs mots. |
Taille et police (CSS — font-size et font-weight de .text-rotate) |
28 px, 800 | Un mot de 40 à 50 px fait mieux voir la 3D. Les lettres grasses gardent assez de surface pour que le dégradé se lise. |
Dégradé (CSS — background de .text-rotate span) |
linear-gradient(135deg, #6366f1, #d946ef) | Changez seulement l'image (background-image) pour garder le découpage au texte. Vérifiez le contraste de la couleur la plus sombre avec votre fond. |
Tour au survol (CSS — 1s et textSpin dans la règle :hover, :focus-visible) |
un tour en 1 s, une fois | 1.6s pour un tour plus solennel. Pour deux tours, écrivez rotateY(720deg) dans textSpin. Supprimez la règle pour garder seulement le balancement. |
FAQ
<a href="…"> à la place du <span> ou autour du conteneur, retirez tabindex="0" et ajoutez a:focus-visible .text-rotate à la règle du tour. Gardez une cible assez grande : 28 px de haut est un minimum pour un doigt.-webkit-background-clip: text puis background-clip: text, ce qui couvre les navigateurs qui ne connaissent que l'une des deux formes. Dans le rare cas où aucune ne passe, -webkit-text-fill-color est en général ignorée aussi et le mot s'affiche en blanc, lisible, sans dégradé.