frontend / css
Transformations 2D et 3D
Explication
Ce que vous allez apprendre
- Déplacer, tourner et redimensionner un élément avec
transformsans perturber le flux du document - Comprendre pourquoi l'ordre des fonctions dans
transformchange le résultat visuel - Construire un effet 3D avec
perspective,transform-style: preserve-3detbackface-visibility - Réaliser une carte "flip" qui se retourne au survol, sans JavaScript
- Choisir
transformplutôt quetop/leftpour des animations fluides et peu coûteuses
Dans quel contexte ?
Une plateforme e-commerce affiche une grille de produits. Au survol, chaque carte doit légèrement s'agrandir et une carte "avis client" doit se retourner pour révéler sa note au clic. Ces deux effets reposent entièrement sur transform, plutôt que sur des changements de width/height qui obligeraient le navigateur à recalculer toute la mise en page à chaque frame.
Étape 1 : déplacer sans perturber le reste
transform permet de déplacer, tourner ou redimensionner visuellement un élément, avec une caractéristique essentielle : cela n'affecte JAMAIS le flux du document, contrairement à changer une margin ou une width.
Étape 2 : ce que ça change concrètement
Un transform: translate(20px, 10px) déplace uniquement l'apparence visuelle de l'élément — les autres éléments de la page continuent de se comporter comme s'il n'avait pas bougé. C'est ce qui rend transform si adapté aux animations fluides.
Étape 3 : le piège de l'ordre des transformations
Combiner plusieurs transformations dans une seule déclaration ne donne PAS le même résultat selon leur ordre. translateX(50px) rotate(45deg) diffère de rotate(45deg) translateX(50px).
Piège fréquent
transform: rotate(45deg) translateX(50px) déplace l'élément selon des axes déjà tournés de 45°, ce qui donne un déplacement en diagonale au lieu d'un déplacement horizontal. Testez toujours visuellement l'ordre de vos fonctions transform.
Étape 4 : pourquoi cet ordre compte
Chaque transformation s'applique en partant du résultat de la précédente, comme des calques successifs : déplacer puis tourner ne fait pas pivoter autour du même point que tourner puis déplacer.
| Propriété | Rôle |
|---|---|
perspective | distance œil-écran, sur le PARENT |
transform-style: preserve-3d | les enfants gardent leur propre profondeur |
backface-visibility: hidden | cache la face arrière d'un élément retourné |
Étape 5 : la 3D, une extension du même principe
Une fois la 2D comprise, les transformations 3D ajoutent simplement un axe de profondeur. perspective définit la distance imaginaire entre l'œil de l'utilisateur et l'écran — plus la valeur est petite, plus l'effet de profondeur paraît prononcé.
Étape 6 : ne pas oublier preserve-3d
Il reste un détail à ne pas oublier : preserve-3d est nécessaire pour que les enfants d'un élément gardent leur propre profondeur, sinon toute la 3D est "aplatie" par défaut.
Le vrai enjeu, la performance
Pour finir, une règle cruciale : animer top/left/width/height force un recalcul complet de la mise en page à chaque image, alors qu'animer transform est traité directement par la carte graphique, sans recalcul de layout.
Bonne pratique
Pour animer une position ou une taille, préférez toujours transform: translate()/scale() à top/left/width/height. Le résultat visuel peut être identique, mais la fluidité (60 images par seconde) ne sera garantie qu'avec transform.
Et ensuite ?
Cette différence de performance sera approfondie plus tard dans le cours. Pour l'instant, la prochaine étape consiste à organiser le CSS d'un gros projet avec BEM, l'utility-first et les cascade layers.
Commandes & code
Transformations 2D et 3D
Déplacer, tourner, redimensionner des éléments sans affecter le flux du document.
/* Transformations 2D */
.deplace { transform: translate(20px, 10px); }
.deplace-x { transform: translateX(20px); }
.tourne { transform: rotate(15deg); }
.agrandi { transform: scale(1.2); }
.agrandi-x { transform: scaleX(1.5); }
.penche { transform: skew(10deg, 0deg); }
/* Combinaison : appliquées de GAUCHE à DROITE, l'ordre change le résultat */
.combo {
transform: translateX(50px) rotate(45deg);
/* translate PUIS rotate : la rotation se fait autour du nouveau centre */
}
.combo-inverse {
transform: rotate(45deg) translateX(50px);
/* rotate PUIS translate : le déplacement se fait selon les axes déjà tournés */
}
/* Point d'origine de la transformation */
.origine-coin {
transform-origin: top left; /* défaut : center */
transform: rotate(45deg); /* pivote depuis le coin, pas le centre */
}/* Transformations 3D */
.conteneur-3d {
perspective: 800px;
/* distance "œil -> écran" : plus petite = effet 3D plus prononcé */
}
.carte-3d {
transform: rotateY(25deg);
transform-style: preserve-3d; /* les enfants gardent leur propre profondeur 3D */
transition: transform 0.4s;
}
.carte-3d:hover {
transform: rotateY(0deg);
}
/* Pattern : carte qui se retourne (flip card) */
.flip-carte {
perspective: 1000px;
}
.flip-carte-interieur {
position: relative;
transform-style: preserve-3d;
transition: transform 0.6s;
}
.flip-carte:hover .flip-carte-interieur {
transform: rotateY(180deg);
}
.flip-face,
.flip-dos {
position: absolute;
inset: 0;
backface-visibility: hidden; /* cache la face qui "regarde vers l'arrière" */
}
.flip-dos {
transform: rotateY(180deg);
}/* Performance : privilégier translate/scale/rotate à top/left/width/height */
/* MAUVAIS : déclenche layout (reflow) à chaque frame */
.mauvais-anim {
transition: left 0.3s, top 0.3s;
}
/* BON : transform est géré par le compositeur GPU, pas le moteur de layout */
.bonne-anim {
transition: transform 0.3s;
}
.bonne-anim:hover {
transform: translate(20px, -20px);
}Résumé
- L'ordre des fonctions dans
transformest significatif : chaque transformation s'applique au repère déjà modifié par la précédente. perspectivesur le PARENT ettransform-style: preserve-3dactivent un vrai rendu 3D en profondeur.backface-visibility: hiddenest indispensable pour les cartes "flip" à deux faces.transform/opacitysont les seules propriétés animables sans déclencher de reflow coûteux.
Exercices pratiques
Mission : une carte avis client qui se retourne dans le mauvais sens
Objectif : Corriger l'ordre des fonctions transform et un flip card mal préparé pour la 3D.
Contexte
Sur avis-client.css, une carte doit légèrement pivoter puis se décaler vers la droite au survol : transform: rotate(15deg) translateX(40px);. Au lieu d'un déplacement horizontal net, la carte part visuellement en diagonale. Par ailleurs, la carte "flip" censée se retourner au clic pour révéler la note utilise .flip-carte-interieur { transform: rotateY(180deg); transition: transform 0.6s; } mais SANS transform-style: preserve-3d sur ce même élément : au clic, la face arrière apparaît immédiatement à l'envers plutôt qu'un vrai effet de retournement en profondeur.