Transformaciones

Qué es una transformación

Transformar un elemento es cambiar cómo se dibuja: moverlo, agrandarlo, girarlo o inclinarlo. Lo decisivo, y lo que hay que entender antes que ninguna otra cosa, es lo que no ocurre:

Una transformación no toca la maqueta. El elemento se pinta movido o girado, pero su hueco sigue exactamente donde estaba, y los elementos de alrededor no se enteran. Es lo mismo que ya vieron con position: relative: lo que cambia es el dibujo, no el sitio.

Esa es la razón de que las transformaciones sean baratas para el navegador, y de que sean la base de las animaciones que veremos después.

Transformaciones 2D

Ocurren en el plano de la pantalla, el mismo en el que está escrito todo lo demás. Hay dos ejes: la X horizontal, positiva hacia la derecha, y la Y vertical, positiva hacia abajo. Sobre ese plano se puede desplazar, escalar, girar e inclinar.

Transformaciones 3D

Añaden un tercer eje, la Z, que no está en la pantalla sino que sale de ella hacia quien mira. Con él, un elemento puede girar como una puerta o como una persiana, mostrando su canto. La pantalla sigue siendo plana, así que lo que se ve es una proyección: el navegador calcula cómo se vería ese giro y lo dibuja.

Esa proyección necesita un dato más, el punto de vista. Sin él, el giro se ve aplastado en lugar de profundo. Se tratará al final.

Transformaciones 2D

Todas se escriben en la misma propiedad, transform, y todas usan una función con su valor entre paréntesis. En las demostraciones, la caja transformada es la del medio; las otras dos permanecen en su sitio.

translate: desplazar

Mueve el elemento. Dos valores: primero el horizontal, después el vertical.

transform: translate(40px, 20px)

<div class="row">
  <div class="caja">1</div>
  <div class="caja marcada">2</div>
  <div class="caja">3</div>
</div>

Admite un solo eje con translateX() o translateY(), y acepta porcentajes, que se miden sobre el propio elemento, no sobre el padre: translateX(50%) lo mueve media caja a la derecha.

scale: escalar

Agranda o encoge. Es un factor, no una medida: 1 es el tamaño original, 1.5 es una vez y media, 0.5 es la mitad.

transform: scale(1.4)

<div class="row">
  <div class="caja">1</div>
  <div class="caja marcada">2</div>
  <div class="caja">3</div>
</div>

Con dos valores se escala cada eje por separado: scale(2, 0.5) duplica el ancho y reduce el alto a la mitad.

rotate: girar

Gira el elemento. El ángulo va en grados, positivo en el sentido de las agujas del reloj.

transform: rotate(20deg)

<div class="row">
  <div class="caja">1</div>
  <div class="caja marcada">2</div>
  <div class="caja">3</div>
</div>

skew: inclinar

Inclina el elemento, como si se empujara uno de sus lados. Es la menos usada de las cuatro.

transform: skew(20deg, 0deg)

<div class="row">
  <div class="caja">1</div>
  <div class="caja marcada">2</div>
  <div class="caja">3</div>
</div>

transform-origin: el punto fijo

Toda transformación ocurre respecto a un punto, y por defecto es el centro del elemento. transform-origin lo cambia. Aquí el mismo giro de antes, pero anclado en la esquina superior izquierda:

transform-origin: top left

<div class="row">
  <div class="caja">1</div>
  <div class="caja marcada">2</div>
  <div class="caja">3</div>
</div>

Varias a la vez

Se escriben seguidas en la misma propiedad, separadas por espacios. El orden importa: se aplican de izquierda a derecha, y cada una arrastra a la siguiente.

transform: rotate(20deg) translateX(40px)

<div class="row">
  <div class="caja">1</div>
  <div class="caja marcada">2</div>
  <div class="caja">3</div>
</div>

En este caso la caja primero gira, y después se desplaza según sus ejes ya girados: no va hacia la derecha de la pantalla, sino hacia la derecha de sí misma. Invirtiendo el orden el resultado es distinto.

Transformaciones 3D

Los tres giros, uno por eje. La caja del medio sigue siendo la transformada.

rotateZ: el eje que sale de la pantalla

El eje Z apunta hacia quien mira, así que girar sobre él es girar en el plano. rotateZ() es exactamente el rotate() que acabamos de ver. Conviene empezar por aquí para entender qué son los tres ejes.

transform: rotateZ(20deg)

<div class="row">
  <div class="caja">1</div>
  <div class="caja marcada">2</div>
  <div class="caja">3</div>
</div>

rotateX: girar sobre el eje horizontal

Gira la caja alrededor del eje X, el que la atraviesa de izquierda a derecha.

transform: rotateX(50deg)

<div class="row">
  <div class="caja">1</div>
  <div class="caja marcada">2</div>
  <div class="caja">3</div>
</div>

rotateY: girar sobre el eje vertical

Gira la caja alrededor del eje Y, que la atraviesa de arriba a abajo.

transform: rotateY(50deg)

<div class="row">
  <div class="caja">1</div>
  <div class="caja marcada">2</div>
  <div class="caja">3</div>
</div>

Opciones extra

perspective: el punto de vista

Es el dato que faltaba. Indica a qué distancia está el espectador de la pantalla. Cuanto menor es el valor, más cerca se está y más exagerado se ve el efecto.

Se escribe como una función más dentro de transform, y siempre la primera:

transform: perspective(400px) rotateY(50deg)

<div class="row">
  <div class="caja">1</div>
  <div class="caja marcada">2</div>
  <div class="caja">3</div>
</div>

Ahora sí: el lado izquierdo se ve más grande porque está más cerca, y el derecho más pequeño porque se aleja. Eso es profundidad.

Un valor mayor, 1000px, atenúa el efecto: equivale a observar desde más lejos.

Otras que existen

perspective-origin mueve el punto desde el que se mira, que por defecto está centrado.