Control más detallado sobre las transformaciones de CSS con propiedades de transformación individuales

Transforma elementos con las propiedades translate, rotate y scale

La propiedad transform de CSS

Para aplicar transformaciones a un elemento, usa la propiedad transform de CSS. La propiedad acepta uno o más <transform-function> que se aplican uno después del otro.

.target {
  transform: translateX(50%) rotate(30deg) scale(1.2);
}

El elemento objetivo se traduce un 50% en el eje X, se rota 30 grados y, por último, se ajusta a un 120%.

Si bien la propiedad transform funciona bien, se vuelve un poco tediosa cuando quieres alterar cualquiera de esos valores de forma individual.

Para cambiar la escala cuando se coloca el cursor sobre ella, debes duplicar todas las funciones en la propiedad de transformación, aunque sus valores no cambien.

.target:hover {
  transform: translateX(50%) rotate(30deg) scale(2); /* Only the value of scale() changed */
}

Las propiedades de transformación individuales

Se envían con Chrome 104 propiedades individuales para las transformaciones de CSS. Las propiedades son scale, rotate y translate, que puedes usar para definir de forma individual esas partes de una transformación.

De esta manera, Chrome se une a Firefox y Safari, que ya admiten estas propiedades.

Navegadores compatibles

  • Chrome: 104.
  • Edge: 104.
  • Firefox: 72.
  • Safari: 14.1.

Origen

Si vuelves a escribir el ejemplo anterior de transform con las propiedades individuales, tu fragmento se convierte en lo siguiente:

.target {
  translate: 50% 0;
  rotate: 30deg;
  scale: 1.2;
}

El orden es importante

Una diferencia clave entre la propiedad transform original de CSS y las propiedades nuevas es el orden en que se aplican las transformaciones declaradas.

Con transform, las funciones de transformación se aplican en el orden en que se escriben, de izquierda (exterior) a derecha (interior).

Con las propiedades de transformación individuales, el orden no es el orden en el que se declaran. El orden siempre es el mismo: primero translate (exterior), luego rotate y, luego, scale (interior).

Eso significa que ambos fragmentos de código proporcionan el mismo resultado:

.transform--individual {
  translate: 50% 0;
  rotate: 30deg;
  scale: 1.2;
}

.transform--individual-alt {
  rotate: 30deg;
  translate: 50% 0;
  scale: 1.2;
}

En ambos casos, los elementos objetivo primero se trasladarán en 50% en el eje X, luego se rotarán en 30deg y, por último, se escalarán en 1.2.

Si se declara una de las propiedades de transformación individuales junto con una propiedad transform, las transformaciones individuales se aplican primero (translate, rotate y, luego, scale) con transform al final (dentro). Puedes encontrar más detalles en la especificación que define cómo se debe calcular la matriz de transformación.

Animaciones

El motivo principal por el que se agregaron estas propiedades es facilitar las animaciones. Supongamos que quieres animar un elemento de la siguiente manera:

Gráfico de fotogramas clave.

Usa transform

Para implementar esta animación con transform, tendrías que calcular todos los valores intermedios para todas las transformaciones definidas y, luego, incluirlos en cada fotograma clave. Por ejemplo, para realizar una rotación en el 10%, también se deben calcular los valores de las otras transformaciones, ya que la propiedad transform los necesita todos.

Gráfico de fotogramas clave con valores intermedios calculados

El código CSS resultante se convierte en lo siguiente:

@keyframes anim {
  0% { transform: translateX(0%); }
  5% { transform: translateX(5%) rotate(90deg) scale(1.2); }
  10% { transform: translateX(10%) rotate(180deg) scale(1.2); }
  90% { transform: translateX(90%) rotate(180deg) scale(1.2); }
  95% { transform: translateX(95%) rotate(270deg) scale(1.2); }
  100% { transform: translateX(100%) rotate(360deg); }
}

.target {
  animation: anim 2s;
  animation-fill-mode: forwards;
}

Usa propiedades de transformación individuales

Con las propiedades de transformación individuales, esto se vuelve mucho más fácil de escribir. En lugar de arrastrar todas las transformaciones de un fotograma clave a otro, puedes segmentar cada transformación de forma individual. Además, ya no es necesario que calcules todos esos valores intermedios.

@keyframes anim {
  0% { translate: 0% 0; }
  100% { translate: 100% 0; }

  0%, 100% { scale: 1; }
  5%, 95% { scale: 1.2; }

  0% { rotate: 0deg; }
  10%, 90% { rotate: 180deg; }
  100% { rotate: 360deg; }
}

.target {
  animation: anim 2s;
  animation-fill-mode: forwards;
}

Usa propiedades de transformación individuales y varios fotogramas clave

Para que tu código sea modular, puedes dividir cada subanimación en su propio conjunto de fotogramas clave.

@keyframes move {
  0% { translate: 0% 0; }
  100% { translate: 100% 0; }
}

@keyframes scale {
  0%, 100% { scale: 1; }
  5%, 95% { scale: 1.2; }
}

@keyframes rotate {
  0% { rotate: 0deg; }
  10%, 90% { rotate: 180deg; }
  100% { rotate: 360deg; }
}

.target {
  animation: move 2s, scale 2s, rotate 2s;
  animation-fill-mode: forwards;
}

Gracias a esta división, puedes aplicar cada conjunto de fotogramas clave por separado como desees, ya que las propiedades transform, que ahora se convirtieron en propiedades individuales, ya no se anulan entre sí. Además, puedes asignarle a cada transformación un tiempo diferente sin necesidad de volver a escribir todo el lote.

Rendimiento

Las animaciones que usan estas propiedades nuevas son tan eficientes como las animaciones de la propiedad transform existente.

Las animaciones de translate, rotate y scale se ejecutan en el compositor de la misma manera que las de transform, por lo que son buenas para el rendimiento de la animación de la misma manera que transform.

Estas propiedades nuevas también funcionan con la propiedad will-change. En general, es mejor evitar el uso excesivo de will-change usándolo en la cantidad mínima de elementos necesarios y durante el menor tiempo posible. Sin embargo, también es bueno ser lo más específico posible. Por ejemplo, si usas will-change para optimizar una animación con las propiedades rotate y filter, debes declararlo con will-change: rotate, filter. Esto es un poco mejor que usar will-change: transform, filter en un caso en el que animas rotate y filter, ya que algunas de las estructuras de datos que Chrome crea de antemano cuando usas will-change son diferentes para transform en comparación con rotate.

Parte de la serie de productos interoperables nuevos