Corso di CSS / Trasformazioni e transizioni CSS

Le trasformazioni spostano, ruotano o scalano l'aspetto renderizzato di una scatola senza ridisporre il contenuto circostante. Le transizioni animano un cambiamento tra i valori delle proprietà, quindi seleziona le proprietà e i tempi con attenzione e fornisci un'alternativa a movimento ridotto.

Comprendere le trasformazioni e il flusso normale

Il flusso del documento si riferisce alla relazione tra il punto in cui un elemento è originariamente posizionato e gli elementi circostanti. Anche se sposti il pulsante verso l'alto su translateY(-.5rem), il paragrafo sottostante non si sposta verso l'alto in base allo spazio in cui il pulsante è stato spostato. Gli elementi trasformati possono sovrapporsi ai contenuti circostanti o uscire dallo schermo, quindi lasciare abbastanza spazio nella loro posizione originale è una priorità piuttosto che aumentare la distanza di spostamento.

funzione Esempio Risultati da osservare
translate() translate(1rem, -.5rem) Sposta di 1rem a destra, 0,5rem verso l'alto
rotate() rotate(15deg) Ruota attorno a un punto di riferimento
scale() scale(1.05) Visualizzato a 1,05 volte la dimensione originale

Solo perché la dimensione sembra più grande non significa che lo spazio occupato dalla scatola prima della trasformazione sarà maggiore. Controlla le proprietà Grid o width per cambiare la larghezza effettiva della colonna della scheda, oppure usa transform per creare un effetto visivo leggermente più grande quando viene premuto. I box inline non sostituiti, come un normale elemento span, non sono trasformabili, quindi specifica display: inline-block se necessario. Le definizioni dei bersagli di trasformazione e dell'elaborazione delle coordinate possono essere trovate nel documento MDN transform.

Confronta ordine di trasformazione e origine

Quando elenchi le funzioni di trasformazione, ogni funzione influisce sul sistema di coordinate utilizzato dalla funzione successiva. Mantenendo invece fisso il sistema di coordinate del genitore, lo stesso risultato si può calcolare applicando le funzioni a un punto da destra verso sinistra. Pertanto, traslazione/rotazione e rotazione/traslazione in genere non producono lo stesso risultato. Nell'esempio seguente, la scatola ruotata di A è visibile dove è stata spostata verso destra, mentre la scatola di B si è spostata nella direzione influenzata dalla rotazione ed è visibile più in basso. Non limitarti a guardare il nome della funzione e presumere che i due risultati siano uguali; confronta le loro posizioni effettive.

Il punto di riferimento di rotazione e ridimensionamento è definito da transform-origin. Se si utilizza left top invece del centro predefinito, ruoterà intorno all'angolo in alto a sinistra. Questo è utile quando si vuole fissare un punto specifico, ad esempio quando si apre un menu, ma la sovrapposizione con il contenuto circostante può cambiare semplicemente modificando il punto di riferimento.

Salva il seguente codice come transform-compare.html in UTF-8 e aprilo nel tuo browser. Non sono necessari file o librerie esterni.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Transform order and origin</title>
  <style>
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; padding: 1rem; color: #183044; font-family: sans-serif; line-height: 1.6; }
main { max-width: 46rem; margin-inline: auto; }
h1 { font-size: 1.5rem; } h2 { font-size: 1.2rem; }
button, input { font: inherit; }
button { cursor: pointer; }
:focus-visible { outline: 3px solid #164f73; outline-offset: 3px; }
.comparisons { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr)); gap: 1rem; }
.slot { padding: 1rem; border: 1px solid #8a9ba7; }
.frame { height: 9rem; display: grid; place-items: center; background: #f0f2f4; }
.box { width: 4rem; height: 2rem; display: grid; place-items: center; background: #166b92; color: white; }
.first { transform: translateX(2rem) rotate(45deg); }
.second { transform: rotate(45deg) translateX(2rem); }
.center { transform: rotate(30deg); transform-origin: center; }
.corner { transform: rotate(30deg); transform-origin: left top; }
  </style>
</head>
<body>
<main>
<h1>The same value also varies depending on the order and reference point</h1>
<div class="comparisons">
  <section class="slot"><h2>Translate, then rotate</h2><div class="frame"><div class="box first">A</div></div></section>
  <section class="slot"><h2>Rotate, then translate</h2><div class="frame"><div class="box second">B</div></div></section>
  <section class="slot"><h2>Center origin</h2><div class="frame"><div class="box center">C</div></div></section>
  <section class="slot"><h2>Top-left origin</h2><div class="frame"><div class="box corner">D</div></div></section>
</div>
</main>
</body>
</html>
  1. Confronta le posizioni di A e B. Se cambi l'ordine delle funzioni di .second in modo che sia lo stesso di A, le posizioni relative delle due caselle saranno le stesse. Dopo la conferma, ritorna all'ordine originale.
  2. C e D hanno lo stesso angolo di rotazione. Modifica solo transform-origin da .corner a center, controlla la differenza nei punti di riferimento e ripristina a left top.
  3. Confronta l'ingrandimento modificando solo la rotazione di C su scale(1.2). L'area esterna alla casella crescerà, ma l'area circostante non verrà riallocata. Dopo la conferma, ripristinala a rotate(30deg).

Scegli le proprietà di transizione e i tempi

transition non cambia stato da solo. Il cambiamento inizia solo quando il valore CSS cambia su hover, focus o cambio di classe. Specifica il nome della proprietà da modificare, la durata, la curva di progressione e il ritardo di avvio; se il ritardo è omesso, il valore predefinito è 0 secondi.

transition: transform 180ms ease 0ms, background-color 180ms ease 0ms;

Qui, 180ms è 0,18 secondi, e ease è una curva che collega dolcemente l'inizio e la fine piuttosto che procedere solo alla stessa velocità. linear cambia a velocità costante. Usa prima tempi brevi e nessun ritardo, poi regola secondo necessità. Aggiungere un lungo ritardo a un pulsante apparentemente non reattivo può rendere difficile notare i risultati delle tue azioni.

Mettere transition sulla regola base permette di operare sia all'entrata che al ritorno. Una transizione dichiarata solo su :hover scompare quando l'hover termina e può produrre un ritorno diverso. Nomina le proprietà deliberatamente invece di usare all. Questo esempio fa transitare transform e background-color; non tutte le proprietà si interpolano allo stesso modo. Per ulteriori dettagli, vedi il documento MDN sulla transizione.

Testa il passaggio del mouse e il focus da tastiera

Salva il codice sottostante come transition-state.html. Quando passi il mouse sopra il pulsante o usi il tasto Tab, il pulsante si sposta verso l'alto e il suo colore di sfondo cambia. I punti di focus sono evidenziati individualmente in blu scuro. Il pulsante è solo a scopo pratico per osservare i cambiamenti di stato e nessuna azione aggiuntiva viene eseguita dopo aver premuto il pulsante.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Transforms and state transitions exercise</title>
  <style>
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; padding: 1rem; color: #183044; font-family: sans-serif; line-height: 1.6; }
main { max-width: 46rem; margin-inline: auto; }
h1 { font-size: 1.5rem; } h2 { font-size: 1.2rem; }
button, input { font: inherit; }
button { cursor: pointer; }
:focus-visible { outline: 3px solid #164f73; outline-offset: 3px; }
.stage { padding: 2rem 1rem; border: 2px dashed #8a9ba7; }
.action { padding: .75rem 1.25rem; border: 1px solid #166b92; border-radius: .4rem;
  color: #183044; background: #eaf4fa; transform: translateY(0);
  transition: transform 180ms ease, background-color 180ms ease; }
.action:hover, .action:focus-visible { transform: translateY(-.5rem); background: #cfe8f4; }
.neighbor { margin-block: 1rem 0; padding: .75rem; background: #f0f2f4; }
@media (prefers-reduced-motion: reduce) {
  .action { transition: none; }
  .action:hover, .action:focus-visible { transform: none; }
}
  </style>
</head>
<body>
<main>
<h1>The paragraph stays in place as the button moves</h1>
<p>Hover over the button or press Tab to focus it.</p>
<div class="stage">
  <button class="action" type="button">Check state</button>
  <p class="neighbor">This paragraph stays in place when the button is transformed.</p>
</div>
</main>
</body>
</html>
  1. Ricorda la posizione superiore del paragrafo sottostante e passa il mouse sopra il pulsante. Solo i pulsanti si muovono e i paragrafi devono rimanere nella stessa posizione.
  2. Modifica la durata in due punti da 180ms a 800ms per osservare l'entrata e il ritorno, poi ritorna al valore originale.
  3. Lascia il tempo così com'è e modifica solo la curva di progresso in linear per il confronto. Poi ripristinala in ease.
  4. Aggiungiamo solo un ritardo 400ms alla fine della prima transizione. Lo sfondo inizia a cambiare subito, mentre transform attende 400ms: osserva la differenza tra i due istanti di avvio. Elimina i ritardi dopo la conferma.
  5. Porta il focus sul pulsante con il tasto Tab ed esci con Shift+Tab. Assicurati che il contorno del focus e il colore di sfondo descrivano lo stato operativo.

Riduci il movimento e controlla gli effetti collaterali

Quando l’utente preferisce ridurre il movimento, nell’esempio le regole per prefers-reduced-motion: reduce eliminano il movimento, lasciando solo il colore di sfondo e i segni di focus. Se si rimuove semplicemente la transizione, il cambiamento avverrà immediatamente, ma la posizione finale a cui ci si è spostati rimarrà. Nell'esempio sopra, abbiamo deciso che il movimento decorativo di per sé non era necessario, quindi anche le trasformazioni al passaggio del mouse e al focus sono state modificate in none. Si prega di fare riferimento alla guida alle impostazioni di riduzione del movimento MDN.

Confronta i due stati modificando le impostazioni del sistema operativo o riproducendo le caratteristiche dei media nel pannello Rendering degli strumenti per sviluppatori del browser. Nelle impostazioni ridotte, il pulsante non dovrebbe muoversi, solo il colore e l'indicatore di focus dovrebbero cambiare. Quando hai finito il laboratorio, ripristina l'emulazione allo stato predefinito.

Un transform diverso da none crea un contesto di sovrapposizione e può stabilire il contenitore per i discendenti absolute e fixed. Se un popup o un elemento fixed si comporta in modo imprevisto, ispeziona gli antenati trasformati. Controlla anche sovrapposizione, focus da tastiera e riduzione del movimento; una transizione fluida da sola non stabilisce un layout utilizzabile. Vedi position: relative, absolute, fixed e sticky, z-index CSS e contesti di sovrapposizione.