Créez vos transformations CSS 3D visuellement : translate, rotate, scale, skew et perspective avec preview live. Code CSS prêt à copier pour vos sites web modernes.
Générateur CSS 3D Transform
Scale
Rotate
Translate
Skew
Perspective
Transform Origin & Backface
.parent {
perspective: 1000px;
perspective-origin: 50% 50%;
}
.element {
transform: translate3d(0px, 0px, 0px) rotateX(0deg) rotateY(0deg) rotateZ(0deg) scale3d(1, 1, 1) skew(0deg, 0deg);
transform-origin: 50% 50%;
backface-visibility: visible;
}
CSS 3D Transform — qu'est-ce que c'est ?
Les transformations 3D en CSS permettent de manipuler des éléments HTML dans un espace tridimensionnel, en ajoutant un axe de profondeur (Z) aux axes horizontaux (X) et verticaux (Y) du modèle 2D classique. Introduites par le module CSS Transforms Level 2, ces fonctions sont aujourd'hui supportées par 98 % des navigateurs (Can I Use, 2024) et sont accélérées matériellement par le GPU — ce qui en fait l'un des leviers les plus puissants pour créer des interfaces modernes et fluides sans recourir à WebGL ou Canvas.
Le point d'entrée : la propriété transform
Toutes les transformations passent par une seule propriété CSS, transform, qui accepte une liste ordonnée de fonctions séparées par des espaces. L'ordre est crucial : rotateX(45deg) translateZ(100px) ne produit pas le même rendu que translateZ(100px) rotateX(45deg), car chaque fonction modifie le repère local utilisé par la suivante.
Pourquoi utiliser des transformations 3D ?
Trois raisons principales justifient l'usage des transforms 3D plutôt que leurs équivalents 2D :
- Performance GPU :
translate3d(),scale3d()etrotate3d()déclenchent une couche de compositing dédiée. Le navigateur les anime sans repaint ni reflow, à 60 fps même sur mobile. - Effets immersifs : flip de cartes, carrousels coverflow, cubes interactifs, parallax — tout effet de profondeur réaliste nécessite la 3D.
- Précision visuelle : la
perspectivecontrôle le réalisme de la perspective conique, ce qu'aucune transformation 2D ne peut faire.
Les axes X, Y, Z et le rôle de la perspective
Comprendre les trois axes du repère CSS est indispensable avant toute transformation 3D :
- Axe X : horizontal, positif vers la droite. Une rotation autour de X fait pivoter l'élément vers l'avant ou l'arrière.
- Axe Y : vertical, positif vers le bas (différent de la convention mathématique). Une rotation autour de Y fait pivoter l'élément de gauche à droite comme une porte.
- Axe Z : profondeur, positif vers le spectateur. Une translation positive en Z rapproche l'élément ; négative, il s'éloigne.
La propriété perspective
Sans perspective, les transformations 3D s'aplatissent : un rotateY(45deg) apparaîtra comme un simple scaleX. La perspective définit la distance entre l'œil du spectateur et le plan Z=0. Plus la valeur est petite, plus l'effet 3D est exagéré (vision grand-angle) ; plus elle est grande, plus l'effet est subtil (vision téléobjectif).
/* Méthode 1 — perspective sur le parent (recommandé pour plusieurs enfants) */
.scene {
perspective: 800px;
perspective-origin: 50% 50%;
}
.scene .card {
transform: rotateY(45deg);
}
/* Méthode 2 — perspective dans le transform (un seul élément) */
.element {
transform: perspective(800px) rotateY(45deg);
}
perspective sur le parent, tous les enfants partagent le même point de fuite — indispensable pour une scène cohérente. Avec perspective() dans le transform, chaque élément a sa propre perspective indépendante.
transform-style: preserve-3d
Par défaut, les enfants transformés sont aplatis dans le plan de leur parent (transform-style: flat). Pour construire des objets 3D composés (cube, carrousel cylindrique), il faut activer preserve-3d sur le conteneur :
.cube-scene {
perspective: 1000px;
}
.cube {
transform-style: preserve-3d; /* essentiel pour cube 3D */
transform: rotateX(-20deg) rotateY(30deg);
}
.cube .face {
position: absolute;
width: 200px;
height: 200px;
}
.cube .face--front { transform: translateZ(100px); }
.cube .face--back { transform: rotateY(180deg) translateZ(100px); }
.cube .face--right { transform: rotateY(90deg) translateZ(100px); }
.cube .face--left { transform: rotateY(-90deg) translateZ(100px); }
.cube .face--top { transform: rotateX(90deg) translateZ(100px); }
.cube .face--bottom { transform: rotateX(-90deg) translateZ(100px); }
transform-origin — point d'ancrage
transform-origin définit le point autour duquel s'appliquent les rotations et le scaling. Par défaut, c'est le centre de l'élément (50% 50%). Modifier cette valeur change radicalement le rendu :
/* Rotation autour du coin inférieur gauche */
.element {
transform-origin: 0 100%;
transform: rotateZ(45deg);
}
/* Effet "ouverture de livre" — origine sur le bord gauche */
.book-page {
transform-origin: 0 50%;
transform: rotateY(-160deg);
}
Toutes les fonctions transform 3D détaillées
translate3d(x, y, z)
Déplace l'élément le long des trois axes. Les unités acceptées sont px, %, em, rem, etc. Important : translate3d déclenche systématiquement la couche GPU même si Z=0, c'est la raison du célèbre transform: translate3d(0,0,0) utilisé pour forcer l'accélération matérielle.
/* Animation de carrousel — translate3d pour la fluidité */
.slide {
transform: translate3d(-100%, 0, 0);
transition: transform 0.4s ease-out;
}
.slide.active {
transform: translate3d(0, 0, 0);
}
rotateX(angle), rotateY(angle), rotateZ(angle)
Trois fonctions distinctes pour faire pivoter l'élément autour de chacun des axes. rotateZ est équivalent au rotate() 2D. Les angles s'expriment en deg, rad, grad ou turn.
/* Flip horizontal — carte qui se retourne */
.card { transition: transform 0.6s; transform-style: preserve-3d; }
.card.flipped { transform: rotateY(180deg); }
/* Animation d'apparition — tilt 3D au survol */
.tile {
transition: transform 0.3s;
}
.tile:hover {
transform: rotateX(-8deg) rotateY(8deg);
}
rotate3d(x, y, z, angle)
Forme générique qui permet de faire pivoter autour d'un axe arbitraire défini par un vecteur (x, y, z). Plus flexible que les trois fonctions précédentes mais moins lisible.
/* Rotation autour de la diagonale — vecteur (1,1,0) normalisé */
.diagonal-flip { transform: rotate3d(1, 1, 0, 180deg); }
/* Équivalence */
.r-x { transform: rotate3d(1, 0, 0, 45deg); } /* = rotateX(45deg) */
.r-y { transform: rotate3d(0, 1, 0, 45deg); } /* = rotateY(45deg) */
scale3d(sx, sy, sz) et scaleZ(sz)
Met à l'échelle l'élément sur les trois axes. scaleZ n'a d'effet visible que si l'élément possède une profondeur (par exemple un autre transform 3D) ou s'il a des enfants positionnés en translateZ dans un parent preserve-3d.
skew(ax, ay) et skewX/Y
Inclinaison de l'élément selon les axes. Techniquement skew est une transformation 2D, mais elle est souvent combinée aux transforms 3D pour des effets de cisaillement. Valeurs acceptées : 0deg à ±89deg (à 90° l'élément disparaît).
/* Effet de "vent" sur une carte */
.windy-card {
transform: perspective(800px) rotateY(15deg) skew(-5deg, 0);
}
matrix3d() — la forme matricielle
Forme la plus puissante : une matrice 4×4 (16 valeurs) qui encode l'intégralité d'une transformation 3D arbitraire. Difficile à écrire à la main, mais générée automatiquement par les outils de design et utilisable pour des interpolations avancées (par exemple en JavaScript via DOMMatrix).
Cas d'usage réels et patterns avancés
Carte qui se retourne (flip card)
Pattern incontournable, présent sur la plupart des sites e-commerce et portfolios :
.flip-card {
perspective: 1200px;
width: 280px;
height: 380px;
}
.flip-card-inner {
position: relative;
width: 100%; height: 100%;
transform-style: preserve-3d;
transition: transform 0.6s cubic-bezier(.4,0,.2,1);
}
.flip-card:hover .flip-card-inner {
transform: rotateY(180deg);
}
.flip-card-face {
position: absolute;
width: 100%; height: 100%;
backface-visibility: hidden; /* masque la face arrière */
}
.flip-card-face--back {
transform: rotateY(180deg);
}
backface-visibility: hidden est essentiel pour qu'une face ne soit visible que lorsque sa caméra la regarde. Sans cette propriété, vous verriez les deux faces simultanément à 90° de rotation.
Tilt 3D au survol de la souris
Effet "parallax" populaire sur les sites créatifs. Le JavaScript écoute le déplacement de la souris et applique des rotations proportionnelles :
const tile = document.querySelector('.tilt-tile');
tile.addEventListener('mousemove', (e) => {
const rect = tile.getBoundingClientRect();
const x = (e.clientX - rect.left) / rect.width - 0.5; // -0.5 → 0.5
const y = (e.clientY - rect.top) / rect.height - 0.5;
tile.style.transform =
`perspective(1000px) rotateY(${x * 20}deg) rotateX(${-y * 20}deg)`;
});
tile.addEventListener('mouseleave', () => {
tile.style.transform = 'perspective(1000px) rotateY(0) rotateX(0)';
});
Carrousel coverflow (style iTunes)
Les éléments adjacents au centre sont reculés et tournés pour simuler un défilement en perspective.
.cover-item {
position: absolute;
transition: transform 0.5s ease;
}
.cover-item.center { transform: translateX(0) translateZ(0) rotateY(0); }
.cover-item.left-1 { transform: translateX(-180px) translateZ(-120px) rotateY(45deg); }
.cover-item.right-1 { transform: translateX( 180px) translateZ(-120px) rotateY(-45deg); }
.cover-item.left-2 { transform: translateX(-300px) translateZ(-240px) rotateY(60deg); }
Apparition cinématique d'un titre
Combinaison de rotateX et translateY pour faire surgir un titre depuis le bas en pivotant :
@keyframes fold-in {
from { transform: perspective(600px) rotateX(-90deg) translateY(40px); opacity: 0; }
to { transform: perspective(600px) rotateX(0) translateY(0); opacity: 1; }
}
.hero-title { animation: fold-in 0.7s cubic-bezier(.2,.7,.3,1) both; }
Bouton "pressé" avec ombre dynamique
Sur :active, on combine un translateZ négatif avec une modification d'ombre pour simuler l'enfoncement.
.btn-3d {
transition: transform .15s, box-shadow .15s;
box-shadow: 0 6px 14px rgba(0,0,0,0.18);
}
.btn-3d:active {
transform: translateZ(-6px);
box-shadow: 0 2px 4px rgba(0,0,0,0.18);
}
Performances, accessibilité et bonnes pratiques
Accélération matérielle GPU
Les transformations 3D créent automatiquement une couche de compositing dédiée. Le navigateur peut alors animer la couche en GPU sans solliciter le moteur de layout. Concrètement, animer transform tourne à 60 fps là où animer top, left ou margin chute à 15-20 fps sur mobile. C'est le pilier de toute animation web performante.
Le piège will-change
will-change: transform indique au navigateur de préparer la couche GPU à l'avance. Très efficace mais à utiliser avec parcimonie : chaque couche consomme de la mémoire vidéo. Appliquer will-change à 200 éléments en même temps peut épuiser le GPU mobile.
/* ✅ Bon : appliqué juste avant l'animation, retiré après */
.card:hover { will-change: transform; }
/* ❌ Mauvais : applied permanently à tous les éléments */
* { will-change: transform; } /* JAMAIS faire ça */
Compatibilité navigateur
Toutes les fonctions 3D listées dans ce générateur sont supportées sans préfixe vendeur sur Chrome 36+, Firefox 16+, Safari 9+, Edge 12+. Les anciens iOS (< 9) requièrent -webkit-transform. preserve-3d est correctement supporté partout depuis 2017.
Accessibilité — prefers-reduced-motion
Certains utilisateurs sont sensibles aux animations (vestibulaire, vertiges). La media query prefers-reduced-motion permet de désactiver ou simplifier les transforms intensifs :
@media (prefers-reduced-motion: reduce) {
.flip-card-inner,
.cover-item,
.tilt-tile {
transition: none !important;
transform: none !important;
animation: none !important;
}
}
Mobile et orientation
Sur mobile, les rotations 3D combinées au scroll peuvent provoquer des saccades. Trois précautions :
- Limiter le nombre d'éléments animés simultanément (max 5-10 sur viewport).
- Désactiver les ombres complexes pendant l'animation : ombres + transform 3D = double couche coûteuse.
- Tester sur appareil moyen-gamme (pas seulement sur le dernier iPhone Pro).
Anti-aliasing et flou de rendu
Certains navigateurs (Chrome, Safari) appliquent un anti-aliasing différent sur les couches GPU. Si le texte transformé paraît flou, deux solutions :
/* Force le rendu net sur Webkit */
.text-transformed {
-webkit-font-smoothing: antialiased;
transform: translateZ(0); /* hack pour stabiliser la couche */
}
/* Empêche le flou sur Firefox */
.text-transformed {
transform: rotateY(45deg) translate3d(0, 0, 0);
backface-visibility: hidden;
}
FAQ — Questions fréquentes
Pourquoi mon élément reste plat malgré rotateX/Y ?
Il vous manque la perspective. Sans elle, les rotations 3D sont projetées orthogonalement (sans effet de profondeur). Ajoutez perspective: 800px; sur le parent ou utilisez transform: perspective(800px) rotateY(...).
Quelle est la différence entre translateZ(0) et translate3d(0,0,0) ?
Aucune différence fonctionnelle visible : les deux forcent le passage en couche GPU. translate3d est légèrement plus explicite et historiquement mieux supporté sur Safari mobile, mais en 2024 les deux sont interchangeables. Privilégiez translate3d par convention.
Comment animer une transform en JavaScript de façon performante ?
Utilisez l'API Web Animations ou modifiez directement element.style.transform dans un requestAnimationFrame. Évitez setInterval et les manipulations de classes dans une boucle.
const el = document.querySelector('.box');
el.animate(
[
{ transform: 'rotateY(0)' },
{ transform: 'rotateY(360deg)' }
],
{ duration: 1000, iterations: Infinity, easing: 'linear' }
);
Mon cube affiche des faces dans le mauvais ordre
Vérifiez que le conteneur a bien transform-style: preserve-3d. Si le bug persiste sur Safari mobile, c'est un bug connu de WebKit : ajoutez will-change: transform ou backface-visibility: hidden sur les faces pour forcer le tri Z correct.
Peut-on combiner filter: blur() et transform 3D ?
Oui, mais avec précaution. Les filter créent une nouvelle stacking context qui peut annuler la propagation de preserve-3d. Si votre cube se met à apparaître plat dès qu'un filter s'applique sur le parent, déplacez le filter sur l'enfant ou créez un wrapper supplémentaire.
Comment éviter le scintillement (flicker) au début de l'animation ?
Trois techniques cumulables : 1) appliquer transform: translate3d(0,0,0) dès le repos (préchauffage GPU) ; 2) ajouter backface-visibility: hidden ; 3) éviter de combiner transition sur plusieurs propriétés non-transform (préférer animer uniquement transform et opacity).
Le générateur produit-il du code compatible avec Tailwind CSS ?
Le code CSS pur est universel et compatible avec n'importe quel framework. Avec Tailwind, vous pouvez transposer le résultat en arbitrary values : par exemple class="rotate-[45deg] translate-z-[100px]" ou utiliser la directive @apply dans une feuille CSS personnalisée.
Conclusion
Les transformations CSS 3D représentent l'un des outils les plus performants et expressifs du CSS moderne. Maîtriser translate3d, rotate3d, scale3d et la perspective permet de créer des interfaces immersives à 60 fps sans une seule ligne de JavaScript ni de WebGL. La courbe d'apprentissage est principalement conceptuelle (comprendre les axes, l'ordre des opérations, la perspective conique) — une fois ces fondamentaux acquis, les possibilités créatives sont illimitées.
Ce générateur visuel vous épargne le calcul mental : combinez les sliders, observez le résultat en temps réel, copiez le code CSS prêt à coller dans votre projet. N'oubliez pas d'ajouter une perspective au parent du futur élément pour reproduire le rendu observé ici.
- Définissez toujours
perspectivesur le parent quand la scène contient plusieurs éléments 3D - Activez
transform-style: preserve-3dpour les objets composés (cubes, carrousels) - Utilisez
backface-visibility: hiddenpour les flips et le tri Z - Préférez
translate3d(0,0,0)àtranslate(0,0)pour profiter du GPU - Animez uniquement
transformetopacitypour le 60 fps - Respectez
prefers-reduced-motionpour l'accessibilité - Évitez d'appliquer
will-changeen permanence — uniquement pendant l'animation