La differenza tra le unità percentuale e fr in Layout griglia CSS

Sto giocando con CSS Grid Layout e ho trovato una domanda per la quale non riesco a trovare una risposta.

Considera il seguente esempio:

:root { --grid-columns: 12; --column-gap: 10px; --row-gap: 10px; } .grid { display: grid; grid-template-columns: repeat(var(--grid-columns), calc(100% / var(--grid-columns))); grid-column-gap: var(--column-gap); grid-row-gap: var(--row-gap); justify-content: center; } [class*=l-] { border: 1px solid red; } .l-1 { grid-column-start: span 1; } .l-2 { grid-column-start: span 2; } .l-3 { grid-column-start: span 3; } .l-4 { grid-column-start: span 4; } .l-5 { grid-column-start: span 5; } .l-6 { grid-column-start: span 6; } .l-7 { grid-column-start: span 7; } .l-8 { grid-column-start: span 8; } .l-9 { grid-column-start: span 9; } .l-10 { grid-column-start: span 10; } .l-11 { grid-column-start: span 11; } .l-12 { grid-column-start: span 12; } 
 
Column 1
Column 2
Column 3
Column 4
Column 5
Column 6
Column 7
Column 8
Column 9
Column 10
Column 11
Column 12

Come puoi vedere le colonne escono dalla larghezza dello schermo a causa della larghezza percentuale impostata con calc(100% / var(--grid-columns)) .

Ma se uso unità fr , funziona perfettamente:

 :root { --grid-columns: 12; --column-gap: 10px; --row-gap: 10px; } .grid { display: grid; grid-template-columns: repeat(var(--grid-columns), 1fr); grid-column-gap: var(--column-gap); grid-row-gap: var(--row-gap); justify-content: center; } [class*=l-] { border: 1px solid red; } .l-1 { grid-column-start: span 1; } .l-2 { grid-column-start: span 2; } .l-3 { grid-column-start: span 3; } .l-4 { grid-column-start: span 4; } .l-5 { grid-column-start: span 5; } .l-6 { grid-column-start: span 6; } .l-7 { grid-column-start: span 7; } .l-8 { grid-column-start: span 8; } .l-9 { grid-column-start: span 9; } .l-10 { grid-column-start: span 10; } .l-11 { grid-column-start: span 11; } .l-12 { grid-column-start: span 12; } 
 
Column 1
Column 2
Column 3
Column 4
Column 5
Column 6
Column 7
Column 8
Column 9
Column 10
Column 11
Column 12

Le risorse utilizzate per trovare una risposta:

  • https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns

  • https://css-tricks.com/snippets/css/complete-guide-grid/

  • https://www.w3.org/TR/css-grid-1/

Sarebbe bello se qualcuno potesse spiegare perché le larghezze percentuali fanno la differenza.

fr

L’unità fr funziona solo con lo spazio libero nel contenitore.

Quindi nel tuo codice:

 grid-template-columns: repeat(12, 1fr); 

… lo spazio libero nel contenitore è distribuito equamente tra 12 colonne.

Poiché le colonne si occupano solo di spazio libero , il grid-column-gap non è un fattore. È stato sottratto dalla larghezza del contenitore prima che fosse determinata la lunghezza fr ( riferimento alla specifica ).

Ecco come il browser esegue il calcolo:

 (free space - gutters) / 12 = 1fr 

%

Quando utilizzi le percentuali …

 grid-template-columns: repeat(12, calc(100% / 12)); 

… il contenitore è diviso in 12 colonne, ciascuna con una larghezza di 8,33333%. Questa è una lunghezza effettiva, a differenza dell’unità fr , che riguarda solo lo spazio libero.

Sia le lunghezze delle colonne che gli intervalli di griglia vengono considerati nella larghezza.

Ecco come il browser esegue il calcolo:

 8.33333% * 12 = 100% + 11 * 10px = 110px 

C’è un trabocco chiaro.

(Nota: le proprietà grid-*-gap applicano solo tra gli elementi della griglia, mai tra gli elementi e il contenitore, per cui il numero di grid-gap è 11, non 13).

Questo funziona:

 grid-template-columns: repeat(12, calc(8.3333% - 9.1667px)); 

Il che si risolve in questo:

  • 12 colonne

  • la larghezza di ogni colonna è determinata prendendo l’intera larghezza del contenitore ( 100% ) e dividendolo per 12

     100% / 12 = 8.3333% (individual column width) 
  • quindi sottrarre le lacune di colonna (ci sono 11)

      10px * 11 = 110px (total width of column gaps) 110px / 12 = 9.1667px (amount to be deducted from each column) 
 .grid { display: grid; grid-template-columns: repeat(12, calc(8.3333% - 9.1667px)); grid-column-gap: 10px; grid-row-gap: 10px; justify-content: center; } .l-1 { grid-column-start: span 1; } .l-2 { grid-column-start: span 2; } .l-3 { grid-column-start: span 3; } .l-4 { grid-column-start: span 4; } .l-5 { grid-column-start: span 5; } .l-6 { grid-column-start: span 6; } .l-7 { grid-column-start: span 7; } .l-8 { grid-column-start: span 8; } .l-9 { grid-column-start: span 9; } .l-10 { grid-column-start: span 10; } .l-11 { grid-column-start: span 11; } .l-12 { grid-column-start: span 12; } [class*=l-] { border: 1px solid red; } 
 
Column 1
Column 2
Column 3
Column 4
Column 5
Column 6
Column 7
Column 8
Column 9
Column 10
Column 11
Column 12

Secondo questa parte della specifica, l’unità fr non è una lunghezza, quindi viene “calcasting” DOPO aver determinato la quantità di spazio libero disponibile all’interno del motore di layout.

La variabile che hai creato nel tuo primo esempio fa parte di un calcolo (100% della larghezza e dividendo per 12) quindi esegue il calcolo PRIMA di passare al motore di layout.

Quando dico motore di layout, lo sto usando come una metafora e non voglio confondere la gente con il processo di rendering che viene fatto dal browser. Sto solo cercando di dire che nel tuo primo esempio stai presentando una serie di numeri che vengono collegati al browser per iniziare il processo di rendering e nel tuo secondo esempio ti stai presentando più di un algoritmo / funzione che il browser può utilizzare per creare il suo layout.