3D Extrude Text
Un empilement de 12 text-shadow graduées et un translate au survol donnent l'illusion d'un bloc extrudé — relief 3D en pur CSS, aucun JavaScript.
Vous aurez accès à la démo interactive avec un compte gratuit.
Cet effet fait partie d'Effect.Labs — 811 effets vanilla, une partie gratuite, une partie premium. Texte comprend 56 effets, dont 4 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
L'effet repose sur un empilement de couches text-shadow. Au repos, 4 ombres décalées de 1 px en 1 px (du bleu-indigo #4f46e5 au violet profond #312e81) esquissent un volume minimal. Au survol, 12 couches prennent le relais : chaque ombre progresse d'1 px supplémentaire — la profondeur apparente atteint 12 px — et les couleurs glissent progressivement vers le quasi-noir (#0f0d24), simulant la face avant et les tranches latérales d'un bloc massif.
La moitié de l'illusion vient du transform: translate(-8px, -8px) appliqué au survol : le texte se déplace vers le haut et la gauche, dégageant les ombres empilées qui restaient cachées derrière lui. L'œil lit ce décalage comme un soulèvement physique. La dernière couche — rgba(0,0,0,.5) 13px 13px 20px avec un grand rayon de flou — joue le rôle d'une ombre portée qui ancre le bloc dans l'espace.
Tout s'anime grâce à une seule règle transition: .3s déclarée sur le sélecteur de base : le navigateur interpole simultanément transform et text-shadow sans JavaScript ni requestAnimationFrame. L'élément doit être affiché en display: inline-block — appliqué ici via .demo-text span — pour que le transform prenne effet sur du texte inline.
Accessibilité
- prefers-reduced-motion : aucune gestion dans le code — la
transitionet letranslatejouent systématiquement. À ajouter manuellement si le projet l'exige :@media (prefers-reduced-motion: reduce) { .text-3d-extrude { transition: none } }. - Contraste de la face : #6366f1 (indigo-500) sur fond #0a0a0f donne un ratio d'environ 4,3:1 — valide WCAG AA pour les grands textes (≥ 3:1) mais légèrement sous le seuil 4,5:1 pour le texte courant. Changer vers #818cf8 (indigo-400) monte le ratio à ~5,9:1.
- Le
<span>aveccursor: pointern'est pas focusable au clavier : aucun:focus-visiblen'est défini. Si l'extrusion doit répondre à la navigation clavier, convertir en<button>ou ajoutertabindex="0"et un état:focus-visible. - Aucun attribut
ariadans le code de base — le texte visible est directement accessible aux lecteurs d'écran, ce qui est correct pour un effet purement décoratif sur du texte statique. Aucunaria-hiddennécessaire.
Compatibilité navigateur
Nécessite text-shadow (IE10+) et transform — supportés dans tous les navigateurs modernes et la plupart des anciens. Zéro dépendance externe.
Sans hover (mobile, tactile), le texte reste dans son état repos — 4 ombres discrètes, pas de translate. Aucune rupture visuelle, le texte reste lisible et l'effet est silencieux.
Le code
Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :
<div class="demo-preview">
<!-- Remplacez le texte par votre contenu -->
<span class="demo-text text-3d-extrude">EXTRUDE</span>
</div>
HTML + CSS + JS complet, prêt à coller — avec des centaines d'effets premium.
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
| color sur .text-3d-extrude | #6366f1 | Couleur de la face avant du texte. Changez aussi les teintes des text-shadow en conséquence (elles sont des variantes plus sombres de cette couleur). |
| text-shadow (état :hover, couches 1–12) | 12 couches, 1 px/couche | Nombre de répétitions = profondeur en px. 6 couches = relief discret, 18 couches = mur épais. Si vous réduisez, réduisez aussi le translate (ex. 6px au lieu de 8px). |
| transform: translate(-8px, -8px) dans :hover | -8px haut, -8px gauche | Distance de soulèvement. Augmentez pour accentuer le décollage. Inversez les signes (+8px, +8px) pour extruder vers le bas-droite. |
| transition sur .text-3d-extrude | .3s | Durée d'animation. .15s = réactif et vif. .5s = cinématique. Remplacez par transition: none pour respecter prefers-reduced-motion. |
| font-size sur .demo-text | 2.5rem | En dessous de 1.8rem, les 12 couches de 1 px se confondent visuellement. Recommandé : ≥ 2rem pour que le relief soit lisible. |
| font-weight sur .demo-text | 800 | Les graisses hautes (700–900) maximisent la surface d'extrusion visible. En dessous de 600, les tranches latérales des ombres sont trop fines pour se distinguer. |
| text-shadow (état repos, couches 1–4) | 4 couches, 1 px/couche | Volume au repos avant survol. Réduire à 1–2 couches pour un état discret, augmenter jusqu'à 6 pour un relief permanent même sans interaction. |
FAQ
translate(-8px, -8px) déplace tout le bloc d'un coup et les ombres restent alignées — le relief est cohérent. Mais les ombres de fin de ligne de la 1ère ligne peuvent chevaucher le début de la 2ème. Pour un rendu optimal, appliquez la classe sur des spans de ligne séparés ou utilisez white-space: nowrap.transform: translate(8px, 8px) et toutes les offsets de text-shadow en positif (1px 1px 0, 2px 2px 0, …). Pour une extrusion verticale seule : translate(0, 8px) avec des offsets 0 1px 0, 0 2px 0, ….font-family sur l'élément parent. Les polices variables permettent même d'animer font-weight en parallèle via transition: .3s font-weight et :hover { font-weight: 900 }, amplifiant visuellement l'extrusion en épaississant la face avant.