Controllo più granulare sulle trasformazioni CSS con proprietà di trasformazione individuali

Trasforma gli elementi con le proprietà translate, rotate e scale

La proprietà CSS transform

Per applicare trasformazioni a un elemento, utilizza la proprietà transform CSS. La proprietà accetta uno o più <transform-function> che vengono applicati uno dopo l'altro.

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

L'elemento scelto come target viene traslato del 50% sull'asse X, ruotato di 30 gradi e infine aumentato di scala fino al 120%.

Sebbene la proprietà transform funzioni perfettamente, diventa un po' noiosa quando vuoi modificare uno di questi valori singolarmente.

Per modificare la scala al passaggio del mouse, devi duplicare tutte le funzioni nella proprietà transform, anche se i relativi valori rimangono invariati.

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

Le singole proprietà di trasformazione

Le singole proprietà per le trasformazioni CSS sono incluse in Chrome 104. Le proprietà sono scale, rotate e translate, che puoi utilizzare per definire singolarmente queste parti di una trasformazione.

In questo modo, Chrome si unisce a Firefox e Safari, che supportano già queste proprietà.

Supporto dei browser

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

Origine

Se riscrivi l'esempio transform precedente con le singole proprietà, lo snippet diventa il seguente:

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

L'ordine è importante

Una differenza fondamentale tra la proprietà CSS transform originale e le nuove proprietà è l'ordine in cui vengono applicate le trasformazioni dichiarate.

Con transform, le funzioni di trasformazione vengono applicate nell'ordine in cui sono scritte, da sinistra (esterno) a destra (interno).

Con le singole proprietà di trasformazione, l'ordine non è quello in cui vengono dichiarate. L'ordine è sempre lo stesso: prima translate (esterno), poi rotate e infine scale (interno).

Ciò significa che entrambi i seguenti snippet di codice restituiscono lo stesso risultato:

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

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

In entrambi i casi, gli elementi scelti come target verranno prima tradotti per 50% sull'asse X, poi ruotati per 30deg e infine scalati per 1.2.

Se una delle singole proprietà di trasformazione viene dichiarata insieme a una proprietà transform, le singole trasformazioni vengono applicate prima (translate, rotate e poi scale) con transform per ultimo (all'interno). Ulteriori dettagli sono disponibili nella specifica che definisce come deve essere calcolata la matrice di trasformazione.

Animazioni

Il motivo principale per cui sono state aggiunte queste proprietà è semplificare le animazioni. Supponiamo che tu voglia animare un elemento come segue:

Grafico dei fotogrammi chiave.

In uso: transform

Per implementare questa animazione utilizzando transform, devi calcolare tutti i valori intermedi per tutte le trasformazioni definite e includerli in ogni fotogramma chiave. Ad esempio, per eseguire una rotazione al 10%, devono essere calcolati anche i valori per le altre trasformazioni, perché la proprietà transform ne ha bisogno di tutti.

Grafico dei fotogrammi chiave con i valori intermedi calcolati.

Il codice CSS risultante diventa:

@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;
}

Utilizzare le singole proprietà di trasformazione

Con le singole proprietà di trasformazione, la scrittura diventa molto più semplice. Anziché trascinare tutte le trasformazioni da un fotogramma chiave all'altro, puoi scegliere come target ogni trasformazione singolarmente. Inoltre, non è più necessario calcolare tutti i valori intermedi.

@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;
}

Utilizzo di singole proprietà di trasformazione e di più fotogrammi chiave

Per rendere il codice modulare, puoi suddividere ogni animazione secondaria in un proprio insieme di fotogrammi chiave.

@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;
}

Grazie a questa suddivisione, puoi applicare ogni insieme distinto di keyframe come preferisci perché le proprietà transform, che ora sono diventate singole proprietà, non si sovrascrivono più. Al di sopra di questo valore, puoi assegnare a ogni trasformazione un tempo diverso senza dover riscrivere l'intero lotto.

Prestazioni

Le animazioni che utilizzano queste nuove proprietà sono altrettanto efficienti delle animazioni della proprietà transform esistente.

Le animazioni di translate, rotate e scale vengono eseguite nel compositore nello stesso modo in cui vengono eseguite le animazioni di transform, quindi sono ottime per le prestazioni delle animazioni come transform.

Queste nuove proprietà funzionano anche con la proprietà will-change. In generale, è meglio evitare di utilizzare eccessivamente will-change utilizzandolo sul numero minimo di elementi necessari e per il periodo di tempo più breve possibile. Ma è anche bene essere il più specifici possibile. Ad esempio, se utilizzi will-change per ottimizzare un'animazione con le proprietà rotate e filter, devi dichiararlo utilizzando will-change: rotate, filter. Questo è leggermente meglio dell'utilizzo di will-change: transform, filter nel caso in cui tu stia animando rotate e filter, perché alcune delle strutture di dati create in anticipo da Chrome quando utilizzi will-change sono diverse per transform rispetto a rotate.

Componente della serie di dispositivi di nuova interoperabilità