Corso di CSS / CSS Grid: repeat, auto-fit, auto-fill e aree

CSS Grid può ripetere le tracce con repeat() e adattare il numero di colonne con auto-fit o auto-fill. I due modi di ripetizione automatica differiscono nel modo in cui gestiscono le tracce vuote; le aree nominate offrono un altro modo per descrivere regioni più grandi della pagina.

Confronta ripetizione fissa e automatica

.cards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}

repeat(3, ...) definisce tre colonne indipendentemente dal numero di schede. Un quarto elemento posizionato automaticamente va nella riga successiva; non aumenta il numero di colonne. Questo differisce dalla ripetizione automatica, che calcola quante tracce possono entrare. Vedi Basi di CSS Grid: tracce, linee e posizionamento.

.cards {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 192px), 1fr));
}

auto-fit calcola quante colonne entreranno con la dimensione minima specificata. Il primo valore di minmax è il minimo, il secondo valore è il massimo, e 1fr divide lo spazio rimanente. Qui min(100%, 192px) garantisce che la larghezza minima della colonna non sia maggiore di quella del suo genitore. Fissare il minimo per le colonne a solo 192px può causare che anche una sola colonna oltrepassi il genitore quando il genitore è più stretto di 192px.

Per un contenitore di 800px, colonne minime di 192px e gap di 16px, tre colonne necessitano di 608px, mentre quattro ne richiedono 816px. Solo tre colonne si adattano. Questo calcolo determina il numero di colonne; la successiva distribuzione dello spazio libero determina la loro larghezza finale. Il testo lungo necessita comunque di una strategia di a capo.

Confronta auto-fill e auto-fit

valore Traccia vuota di ripetizione dopo il posizionamento degli elementi Schermo grande con pochi elementi
auto-fill Mantieni le tracce vuote Spazio colonna vuoto lasciato
auto-fit Comprimi le tracce ripetute senza elementi Le tracce occupate si espandono nello spazio disponibile

Entrambi i valori calcolano inizialmente le colonne ripetute che possono contenere. La differenza con auto-fit riguarda il processo di collasso delle tracce ripetute vuote dopo il posizionamento. Se gli elementi riempiono tutte le colonne, i due valori possono sembrare simili, quindi rendi i contenitori più ampi e metti meno schede quando confronti. Anche quando tutte le schede si adattano a una colonna su uno schermo piccolo, la differenza è difficile da vedere. Le regole della ripetizione automatica sono descritte in MDN: repeat() .

Comprendere il posizionamento automatico e l'ordinamento denso

Gli elementi che non specificano una posizione vengono posizionati riga per riga secondo l'impostazione predefinita grid-auto-flow: row. Anche se l'elemento precedente occupa un'area ampia e viene creato uno spazio vuoto, il posizionamento predefinito non torna continuamente allo spazio vuoto durante il posizionamento dell'elemento successivo. Questo comportamento predefinito rende più facile comprendere l'ordine HTML e la progressione visiva.

grid-auto-flow: row dense può riempire lo spazio vuoto davanti con elementi più piccoli che compaiono successivamente nell’HTML. Sebbene la disposizione diventi più compatta, l'ordine in cui appare sullo schermo e l'ordine del DOM (Document Object Model) possono differire. La posizione CSS non riordina l'HTML, quindi il focus della tastiera e l'ordine di lettura devono essere considerati insieme. Per passaggi numerati in modo significativo, registrazioni cronologiche e voci di modulo, mantenere l'ordine è più importante che eliminare gli spazi vuoti. Puoi controllare le condizioni di posizionamento automatico nella descrizione grid-auto-flow di MDN.

Esegui l'esempio di ripetizione automatica

Salva l'esempio come grid-auto-repeat.html. La prima sezione ha due schede in un contenitore limitato a 800px. La seconda sezione utilizza due link che coprono due colonne e due che coprono una colonna, lasciando un vuoto che ti permette di confrontare il posizionamento ordinario con dense.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>grid-auto-repeat.html</title>
  <style>
* { box-sizing: border-box; }
body { margin: 16px; font: 16px/1.6 sans-serif; color: #243447; }
h1 { font-size: 24px; } h2 { font-size: 20px; margin-top: 32px; }
a { color: #145f8f; } a:focus-visible { outline: 3px solid #b4470b; outline-offset: 3px; }
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 192px), 1fr));
 gap: 16px; width: min(100%, 800px); }
 .cards > div { min-width: 0; padding: 16px; background: #dceefa; overflow-wrap: anywhere; }
 .flow { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px;
 grid-auto-flow: row; max-width: 600px; margin-top: 16px; }
 .flow > a { padding: 12px; background: #e8f5de; }
 .flow > .wide { grid-column: span 2; }
  </style>
</head>
<body>
<h1>Comparing empty repeated columns</h1><div class="cards"><div>First card</div><div>Second card</div></div>
<h2>Default auto-placement</h2><div class="flow"><a class="wide" href="#result">1: two spaces</a><a class="wide" href="#result">2: two spaces</a><a href="#result">3: One space</a><a href="#result">4: one space</a></div>
<p id="result">This is the destination of the automatic-layout link.</p>
</body>
</html>
  1. Su uno schermo ampio, se la prima sezione è di 800px, le due schede in auto-fit occuperanno ciascuna 392px. Sostituendo solo auto-fit con auto-fill si mantengono le tre colonne, lasciando le prime due colonne di schede a circa 256px e una colonna vuota. Dopo la conferma, ripristina a auto-fit.
  2. Copia altri div nella prima sezione fino a farne quattro. Tre colonne sono piene e una quarta scheda è posizionata nella riga successiva. In questa condizione, non ci sono colonne ripetute vuote, il che riduce la differenza tra i due valori. Dopo la pratica, torna alle originali due schede.
  3. Restringi lo schermo per assicurarti che la larghezza del contenitore sia inferiore a 192px. Grazie a min(100%, 192px), una colonna si adatterà al contenitore. Modificare il minimo a solo 192px potrebbe causare un overflow in aree più strette. Dopo il confronto, l'espressione originale viene ripristinata.
  4. Controlla lo spazio vuoto dopo il link 1 e la posizione del link 3 in .flow. Se cambi solo grid-auto-flow in row dense, il numero 3 verrà posizionato nello spazio vuoto precedente. Con Tab, verifica se l'ordine 1 → 2 → 3 → 4 viene mantenuto. Torna a row dopo la pratica.

Definisci le regioni della pagina con aree nominate

Piuttosto che calcolare separatamente numeri di colonne e righe, è più semplice comprendere l'intento del layout della pagina esprimendo grandi sezioni con nomi come header·main·aside·footer. Ogni stringa in grid-template-areas rappresenta una riga, e i nomi separati da spazi all'interno della stringa sono celle. Il valore grid-area del figlio deve corrispondere al suo nome per entrare in quell'area. Come modificare la configurazione delle colonne in base alla larghezza dello schermo è spiegato in Media query CSS e breakpoint basati sul contenuto.

Ripetere lo stesso nome su più celle crea un'area rettangolare. Le aree non possono avere la forma di una L o di un'isola isolata. Ogni riga deve avere lo stesso numero di celle, e le celle da lasciare vuote sono indicate con un punto (.). Se una dichiarazione non è valida, il browser non la rispetterà, il che potrebbe far sembrare un posizionamento automatico. Puoi verificare le condizioni valide dell'area nella descrizione delle grid-template-areas di MDN.

Salva il codice qui sotto come grid-areas.html. Su desktop, il corpo e le informazioni di supporto sono posizionati uno accanto all'altro, e a 640px o meno, sono in un'unica colonna. Secondo il layout dello schermo, l'ordine HTML non è stato invertito, ma il testo principale viene prima delle informazioni ausiliarie.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>grid-areas.html</title>
  <style>
* { box-sizing: border-box; }
body { margin: 16px; font: 16px/1.6 sans-serif; color: #243447; }
h1 { font-size: 24px; } h2 { font-size: 20px; margin-top: 32px; }
a { color: #145f8f; } a:focus-visible { outline: 3px solid #b4470b; outline-offset: 3px; }
.page { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
 grid-template-areas: "header header" "main aside" "footer footer"; gap: 16px; max-width: 1000px; }
 .page > * { min-width: 0; padding: 20px; background: #dceefa; overflow-wrap: anywhere; }
 header { grid-area: header; } main { grid-area: main; } aside { grid-area: aside; } footer { grid-area: footer; }
 @media (max-width: 640px) {
 .page { grid-template-columns: minmax(0, 1fr); grid-template-areas: "header" "main" "aside" "footer"; }
 }
  </style>
</head>
<body>
<h1>Page area names</h1><div class="page"><header>Site title</header><main><h2>Main content</h2><p>This is the main content area. The HTML order keeps it first on mobile, too.</p></main><aside>Related information</aside><footer>Contact and site information</footer></div>
</body>
</html>
  1. Assicurati che l'intestazione e il piè di pagina occupino due colonne su uno schermo ampio. Se riduci lo schermo a 640px o meno, header → main → aside → footer saranno in una colonna. Vedi perché è necessario cambiare insieme le definizioni di colonna e le stringhe delle aree.
  2. Cambia soltanto il valore grid-area di aside usando un nome diverso. La connessione tra l'area aside riservata nel template e l'elemento effettivo potrebbe essere disconnessa e non collocata nello slot previsto. Ripristina il nome a aside.
  3. Se cambi solo il template per schermo ampio in "header header" "header aside" "footer footer", l’area header formerebbe una L e la dichiarazione grid-template-areas sarà non valida. Dopo aver confermato l'applicazione negli Strumenti per Sviluppatori, le tre stringhe originali vengono ripristinate.

In pratica, è più facile da mantenere se si separa l'area per creare colonne in base al numero di schede dall'area per nominare le sezioni della pagina. L'auto-ripetizione determina il numero e la larghezza minima, mentre i nomi delle regioni determinano la struttura della pagina e i punti di transizione. Prima di cercare di forzare i due in un'unica regola, decidi quale problema ciascun contenitore sta cercando di risolvere.