02 Capítulo 2 · Lección 9

Transform Origin

Redactado por
Author Sebastian V.
Fecha de publicación

09/07/2024

Tiempo de lectura

7 min

Tema

CSS Transform

El pivot point: desde dónde todo comienza

Piensa en la aguja de un reloj. Cuando el reloj marca las 12 y avanza hacia la 1, la aguja gira. Pero no gira desde su centro: gira desde su extremo inferior, anclada en el centro del reloj. Si girara desde su propio centro, haría algo completamente diferente, nada que se parecería a un reloj.

Este concepto de "desde dónde gira un elemento" se llama punto de origen (transform-origin), y es uno de los conceptos más poderosos y subutilizados de todo CSS Transform. Sin entenderlo, muchas rotaciones y escalas no se comportarán como esperas.

¿Qué es transform-origin?

Por defecto, todas las transformaciones (rotate, scale, skew) tienen su punto de origen en el centro exacto del elemento, que se representa como 50% 50% o center center.

transform-origin te permite mover ese punto a cualquier lugar: una esquina, un borde, un punto exacto en píxeles, o fuera del elemento por completo:

  • transform-origin: top left — Esquina superior izquierda. Ideal para menús que se despliegan desde la esquina.
  • transform-origin: bottom center — Centro del borde inferior. Esencial para agujas de reloj.
  • transform-origin: right center — Centro del borde derecho. Útil para elementos que "crecen" hacia la izquierda.
  • transform-origin: 20px 80px — Valores exactos en píxeles para posicionamiento preciso.

Impacto en rotaciones

La diferencia visual más dramática se aprecia con rotate(). Si tienes un rectángulo y lo rotas 90 grados:

  • Con transform-origin: center (defecto): El rectángulo gira sobre su centro y termina en una posición completamente diferente.
  • Con transform-origin: top left: La esquina superior izquierda permanece fija como un pivote y el rectángulo "cae" hacia la derecha desde ahí.

Impacto en scale (escalado)

Con scale(2) y el origen por defecto, el elemento crece hacia todos lados por igual desde su centro. Pero si cambias el origin a top left, el elemento crecerá hacia abajo y a la derecha, anclándose en su esquina superior izquierda. Esto es muy útil para menús desplegables que "crecen" desde el botón que los activa.

Caso real: El menú que se despliega

Cuando un menú desplegable de una aplicación moderna aparece debajo de su botón (como el menú de usuario en GitHub o Vercel), visualmente parece que "crece" desde el botón hacia abajo. La técnica exacta: se aplica scale(0) al estado inicial y scale(1) al estado visible, con transform-origin: top right (o la esquina correspondiente al botón) para que el crecimiento empiece desde donde está el cursor.

Consejo profesional

Recuerda que transform-origin debe definirse ANTES de que ocurra la transformación, en el estado base del elemento (no en el :hover). Si lo defines dentro del selector :hover, el elemento saltará de posición bruscamente al hacer hover antes de aplicar la animación.

Agujas que giran desde su base

> _
<div class="reloj-contenedor">
  <div class="aguja aguja-hora"></div>
  <div class="aguja aguja-minuto"></div>
  <div class="centro-reloj"></div>
</div>
> _

Un mini reloj CSS. Las agujas rotan desde su extremo inferior gracias a transform-origin: bottom center. Sin este ajuste, girarían desde su propio centro y el efecto sería completamente diferente.

Errores comunes

01
Definir transform-origin en el estado :hover Si defines transform-origin solo en el :hover, el elemento cambia de pivot point bruscamente al entrar al hover antes de que la animación comience, generando un "salto" visual desagradable.
02
No considerar el transform-origin al escalar desde un borde Si quieres que un menú crezca desde la esquina superior derecha, necesitas transform-origin: top right antes de usar scale(0) → scale(1). Sin este cambio, el menú crecerá desde su centro y aparecerá en el lugar equivocado.

Controla el pivot

Crea un menú desplegable animado con scale(0) → scale(1) que aparezca desde la esquina correcta de su botón trigger. El secreto está en transform-origin.

01 Crea un div rectangular y aplica rotate(45deg) y observa desde qué punto gira
02 Añade transform-origin: top left y repite el rotate(45deg)
03 Prueba transform-origin: bottom right para una rotación opuesta
04 Crea una aguja de reloj que gire desde su base inferior usando transform-origin: bottom center