Transforms 3D CSS
Optional Advanced acaba de ajustar puntero, caret y cromo nativo. Esta última sesión opcional es otra caja de herramientas: transforms 3D. Das a una tarjeta un punto de fuga y la inclinas en profundidad. No rehaz la lección 2D de translate / scale al pasar el ratón, ni eliges cursores ni asas de resize.
Respuesta directa
Los transforms 3D de CSS usan la misma propiedad transform que el 2D, más profundidad. Pon perspective en un padre para que los hijos compartan un punto de fuga (perspective-origin lo mueve). rotateX y rotateY inclinan en los ejes horizontal y vertical; rotateZ es el giro plano que ya conoces. translateZ se acerca o aleja del observador. transform-style: preserve-3d mantiene a los hijos en una escena en vez de aplanarlos. backface-visibility: hidden oculta una cara cuando se da la vuelta — útil en una tarjeta de dos caras. El hueco de maquetación sigue igual que en 2D. Ángulos modestos. Respeta prefers-reduced-motion.
Por qué no es movimiento 2D ni cromo de UI
La lección de transforms 2D enseñó movimiento en el plano: translate, rotate, scale, skew y transform-origin como bisagra. Eso sigue valiendo. El 3D añade una perspective tipo cámara y ejes extra. El CSS de interfaz era cromo de interacción (cursor, resize, caret-color, appearance). Una tarjeta girada no necesita una mano mentirosa, y el asa de un textarea no es un punto de fuga. Si solo quieres un salto de 2px, quédate en 2D.
Perspective — la cámara en el padre
perspective es una longitud: valores más pequeños se sienten más cerca y dramáticos; más grandes, más planos. Ponla en el escenario, no en cada cara, para que los hermanos compartan un punto de fuga.
.stage {
perspective: 800px;
perspective-origin: 50% 40%;
}
.card-3d {
transform: rotateY(18deg);
transform-origin: center;
}
También puedes escribir transform: perspective(800px) rotateY(18deg) en un elemento. Esa cámara es solo de esa caja. Para un cubo o una fila de baldosas, perspective en el padre es más calmo. perspective-origin es el primo del punto de fuga de transform-origin: no sustituye el pivote de la cara que gira.
Ejes — rotateX, rotateY, rotateZ
Piensa en un libro. rotateY abre la tapa izquierda–derecha. rotateX la asiente hacia ti o lejos. rotateZ gira en la página — el rotate() 2D que ya sabes.
.tile-y {
transform: rotateY(-22deg);
}
.tile-x {
transform: rotateX(12deg);
}
.tile-z {
transform: rotateZ(8deg);
}
Encadena con funciones 2D cuando haga falta: rotateY(16deg) translateZ(24px). El orden importa: las posteriores corren en el espacio local de las anteriores. Una sola lista transform, como en 2D. Un rotateX(80deg) enorme en todo un artículo es feria, no interfaz.
translateZ — distancia, no un empujón de layout
Con perspective, un translateZ positivo suele venir hacia el observador. Los vecinos del documento no ceden sitio; solo se mueve la pintura, como el translate 2D.
.stage {
perspective: 900px;
}
.pop-face {
transform: translateZ(40px) rotateY(-8deg);
}
.back-face {
transform: translateZ(-28px);
}
Usa translateZ para separar caras de una escena, no para fingir margin o un z-index cotidiano. z-index sigue ordenando cajas superpuestas en layout 2D; la distancia 3D es otra palanca. Si el trabajo es «subir un chip 2px», basta el translateY de la lección 2D.
preserve-3d — conserva la escena, no aplanes
Por defecto un padre aplana a los hijos transformados (transform-style: flat). Se pierde la relación 3D. Para un cubo, una tapa apilada o una tarjeta de dos caras, pon preserve-3d en el envoltorio que gira.
.scene {
perspective: 700px;
}
.rig {
transform-style: preserve-3d;
transition: transform 0.45s ease;
}
.rig.is-flipped {
transform: rotateY(180deg);
}
.face {
position: absolute;
inset: 0;
backface-visibility: hidden;
}
Cada ancestro que deba guardar profundidad necesita preserve-3d: un padre flat olvidado convierte el cubo en póster. Lo habitual: perspective en el escenario exterior y preserve-3d en el armazón interior: cámara fuera, juntas dentro.
backface-visibility — oculta el reverso
Cuando una cara pasa de 90°, verías su espejo. backface-visibility: hidden quita ese reverso. Empareja dos caras: frente rotateY(0), dorso rotateY(180deg), ambas position: absolute en el mismo armazón.
.card-rig {
position: relative;
transform-style: preserve-3d;
}
.card-front,
.card-back {
position: absolute;
inset: 0;
backface-visibility: hidden;
}
.card-back {
transform: rotateY(180deg);
}
Sin dorsos ocultos aparece un fantasma del frente. Esto no es user-select: none ni appearance: none. Ocultas una cara pintada en 3D; no le quitas la piel a un checkbox.
3D frente a transform 2D frente a cromo de UI
📊 3D vs 2D transform vs UI chrome
| Tool | Job | Poor fit |
|---|---|---|
perspective + rotateX / rotateY / translateZ |
Escena de profundidad: inclinación, distancia, punto de fuga compartido | Hover cotidiano de 2px; forma del puntero |
2D translate / rotate / scale / skew |
Movimiento en el plano; bisagra de origin | Cubo sin preserve-3d |
transform-style / backface-visibility |
Caras 3D anidadas; ocultar el reverso | Color del caret; resize de textarea |
UI (cursor, resize, appearance…) |
Cromo de interacción en controles | Puntos de fuga; volteo de tarjeta |
Optional Advanced ya estilizó controles. Effects & Motion ya enseñó el mapeo 2D. Esta sesión es la capa de profundidad sobre transform. Un cursor: pointer en un título porque tiene rotateY no lo hace 3D. perspective en un login no sustituye resize en un campo de notas.
Hábitos calmos
Mantén la perspective en cientos de píxeles para tarjetas de UI (600px–1200px es un rango sano). No pongas perspective: 40px en body. Empareja :hover o una clase con un transition corto en transform — igual que en 2D. Cierra el adorno con prefers-reduced-motion: reduce (none o un empujón 2D mínimo). El foco de teclado sigue necesitando un anillo visible; un volteo no es un estilo de foco.
.preview {
perspective: 1000px;
}
.preview .plate {
transition: transform 0.3s ease;
}
.preview:hover .plate {
transform: rotateY(-10deg) rotateX(4deg);
}
@media (prefers-reduced-motion: reduce) {
.preview .plate,
.preview:hover .plate {
transition: none;
transform: none;
}
}
Ese hover es una inclinación, no el lift 2D translateY(-0.15rem) del chip ni resize: vertical en un campo. Si quien prefiere menos movimiento quiere una tarjeta quieta, hazle caso.
Pruébalo tú
- Envuelve una tarjeta en
.stage { perspective: 800px; }y ponrotateY(20deg)en el hijo — luego pasaperspectivealtransformdel hijo y compara baldosas hermanas. - Monta una tarjeta de dos caras:
preserve-3den el armazón,backface-visibility: hiddenen ambas, dorso conrotateY(180deg). - Añade
translateZ(32px)al plano frontal; comprueba que los vecinos de layout no se mueven. - Voltea con una clase y
transition: transform— luego aplana conprefers-reduced-motion. - No lo resuelvas con
cursor,resizeni un hover solo 2D contranslateY.
Errores frecuentes
perspective: 50pxenbodyhasta deformar toda la página- Olvidar
preserve-3den el envoltorio y extrañarse de un cubo plano - Tratar el lift 2D del chip (
translateY) como lección 3D - Usar cromo de UI (
cursor,resize,appearance) como si fuera profundidad backface-visibilityen el escenario en vez de en las caras- Ignorar
prefers-reduced-motionen volteos grandes derotateY - Esperar que el 3D cambie el flujo del documento como
margin
Resumen
- Los transforms 3D dan profundidad a
transform: perspective,rotateX/rotateY,translateZ - Pon perspective en la escena padre; preserve-3d para que las caras anidadas sigan en ese espacio
- backface-visibility: hidden oculta una cara que se ha dado la vuelta
- Ni lección de hover 2D ni cromo de interfaz
- Ángulos modestos; respeta el movimiento reducido
- Última sesión CSS de este curso: Optional Advanced termina aquí; no hay más slug CSS en el mapa
🧠 Pon a Prueba tu Conocimiento
Pon a Prueba tu Conocimiento
Ponte a prueba con este cuestionario interactivo y descubre qué tan bien entiendes el tema
📝 Instrucciones
- Lee cada pregunta cuidadosamente
- Selecciona la mejor respuesta para cada pregunta
- Puedes repetir el quiz tantas veces como quieras
- Tu progreso se mostrará en la parte superior