Scavare nella proprietà di visualizzazione: griglie fino in fondo

Pubblicato: 2022-03-10
Riassunto veloce ↬ Continuando una serie sulla proprietà display nei CSS, questa volta Rachel Andrew dà un'occhiata a cosa succede quando usi la griglia come valore di visualizzazione, con informazioni aggiunte su come la griglia secondaria cambia quel comportamento.

Oggi daremo un'occhiata a cosa succede quando utilizziamo display: grid e come potremmo usare il nuovo valore della sottogriglia di grid-template-columns grid-template-rows per consentire le griglie fino in fondo attraverso il nostro markup , che si relazionano tra loro.

Questo articolo fa parte di una serie che esamina vari aspetti della proprietà di display CSS ed è il seguito dei primi due articoli:

  1. I due valori di display
  2. Generazione di scatole
  3. Griglie fino in fondo

Cosa succede quando creiamo un contenitore a griglia?

CSS Grid Layout viene attivato utilizzando display: grid . Se hai letto il primo articolo di questa serie, saprai che il significato effettivo di questa proprietà a valore singolo è display: block grid . Otteniamo una casella a livello di blocco che è definita come un contenitore della griglia , con figli diretti che sono elementi della griglia e partecipano al layout della griglia.

Se dai un'occhiata alle specifiche di visualizzazione, le vedrai nella tabella che definisce tutti i diversi valori per la display . Le parole grid container sono collegate alla definizione di grid container nella Grid Specification. Pertanto, per scoprire cosa significhi effettivamente questo dobbiamo andare a guardare lì. Quando lo facciamo, otteniamo alcuni utili chiarimenti sul comportamento di un contenitore a griglia.

Altro dopo il salto! Continua a leggere sotto ↓

Si dice che un contenitore di griglia stabilisca un Contesto di formattazione della griglia che è simile a un Contesto di formattazione a blocchi (BFC). Ho scritto un'ampia guida al contesto di formattazione dei blocchi. In quell'articolo scoprirai due cose su un BFC che sono le stesse per un contesto di formattazione della griglia. I float non si intromettono nel contenitore della griglia e i margini del contenitore non si contraggono con quelli del contenuto.

Ci sono differenze, tuttavia, solo una volta che entriamo nel contenitore della griglia. I figli di un contenitore della griglia e non partecipano al layout a blocchi e inline, sono elementi della griglia e quindi partecipano al layout della griglia. Ciò significa che alcune cose a cui siamo abituati nel layout a blocchi e inline non sono vere.

Se un elemento nel layout viene spostato o deselezionato, le proprietà float e clear non hanno effetto una volta che l'elemento diventa un elemento della griglia. La proprietà vertical-align non ha effetto e gli pseudo-elementi ::first-letter e ::first-line non possono essere utilizzati.

Il fatto che un elemento non possa essere sia mobile sia un elemento della griglia è utile in termini di creazione di fallback. Quando si crea un fallback per i browser che non supportano la griglia usando i float (quando la griglia è supportata), non è necessario fare nulla di speciale: il float viene sovrascritto.

Delineo questo approccio nel mio articolo sul supporto dei browser senza griglia. Ci sono situazioni in cui il comportamento si è rivelato problematico, sebbene questi problemi possano essere risolti utilizzando un'altra parte di CSS, come descritto in questo post, decomprimendo un problema con griglia e float, "Layout editoriali, esclusioni e griglia CSS".

Detto questo, se non facciamo nient'altro che cambiare il valore di display in grid , non vedremo molta differenza nel nostro layout. I figli diretti sono elementi della griglia, tuttavia, per impostazione predefinita, si ottiene una griglia a una colonna. Una griglia ha sempre una colonna e una riga. Il resto delle righe che possiamo vedere dopo aver fatto questo sono righe implicite, cioè righe create per contenere il contenuto.

Un set di carte disposte una sotto l'altra in un'unica colonna.
Quando creiamo un contenitore a griglia senza colonne, otteniamo una griglia a una colonna. (Grande anteprima)

Possiamo iniziare a formare qualcosa che ci assomigli di più a una griglia dando un valore alla proprietà grid-template-columns . La proprietà prende un tracklist come valore; se gli do tre tracce da 1fr, ora ci troviamo con una griglia a tre colonne e l'uso della proprietà gap mi dà spazio tra quelle carte.

Ora abbiamo qualcosa che ci sembra una griglia:

Carte disposte su tre colonne e due file
Definiamo alcune tracce di colonna e uno spazio vuoto per ottenere un layout della griglia evidente (anteprima grande)

Ciascuno degli elementi della griglia nel nostro esempio ha figli propri. Le carte hanno intestazioni e piè di pagina e un'area per il contenuto principale della carta. Questi figli sono elementi della griglia, ma i loro figli sono tornati al blocco e al layout inline. L'intestazione, l'area del contenuto e il piè di pagina non eseguono alcuna griglia come le cose. Questo perché quando cambiamo il valore di display in grid , non eredita ma solo i figli diventano elementi della griglia; i loro figli tornano al layout a blocchi.

Griglie di nidificazione

Se una carta ha più contenuto delle altre carte, le carte in quella riga diventano più alte. Il valore iniziale di align-items per gli elementi della griglia è stretch . Le nostre carte si estendono a tutta altezza. Gli oggetti all'interno, tuttavia, sono in blocco normale e flusso in linea e quindi non si allungano magicamente per riempire la carta. (Questo è il motivo per cui nell'immagine sopra puoi vedere che le carte con meno contenuti hanno uno spazio vuoto in basso.)

Se lo volessimo (per fare in modo che quel piè di pagina si trovi sempre in basso), potremmo anche trasformare il nostro elemento della griglia in una griglia. In questo caso, una griglia a colonna singola è tutto ciò di cui abbiamo bisogno. Possiamo quindi definire tracce di riga, dando all'area in cui si trova il div con una classe di contenuto, una dimensione della traccia di 1fr . Ciò fa sì che occupi tutto lo spazio disponibile nel contenitore e spingerà il piè di pagina in fondo alla scheda.

Guarda la penna [display: subgrid is not what we want](https://codepen.io/rachelandrew/pen/PvQzeG) di Rachel Andrew.

Guarda il display con penna: la sottogriglia non è ciò che vogliamo di Rachel Andrew.

Puoi fare questo annidamento di griglie quanto ti serve. Non lo considero davvero un nidificazione poiché non stiamo creando tabelle nidificate qui e di solito utilizziamo gli elementi HTML strutturali già presenti. Stiamo solo cambiando il valore di display un livello alla volta in quello che è più appropriato per i figli di quell'elemento. Potrebbe essere un layout flessibile o un layout a griglia, ma molto spesso sarà un layout a blocchi e in linea. In tal caso, non è necessario fare nulla perché è ciò che accade per impostazione predefinita.

Allineare le intestazioni e i piè di pagina

Come abbiamo visto ora, se vogliamo un set di carte disposte su una griglia, e vogliamo che vengano visualizzate all'altezza della carta più alta, e vogliamo che i piè di pagina siano spinti in fondo alla carta, abbiamo bisogno di pochissimi CSS . Il layout CSS per l'esempio sopra è il seguente:

 .cards { display: grid; gap: 20px; grid-template-columns: 1fr 1fr 1fr; } article { display: grid; grid-template-rows: auto 1fr auto; row-gap: 20px; }

E se vogliamo che il colore di sfondo delle intestazioni e dei piè di pagina sia allineato? Ogni scheda è un elemento della griglia, ma le intestazioni e i piè di pagina si trovano nella griglia dell'elemento. Non hanno alcuna relazione tra loro e quindi non possiamo metterli in fila. Qui sarebbe bello se potessimo in qualche modo ereditare la griglia attraverso i bambini.

Se potessimo definire una griglia sul genitore che avesse tre righe, quindi posizionare le carte su queste tre righe e fare in modo che l'intestazione, il contenuto e il piè di pagina si trovino ciascuno in una delle righe. In questo modo, ogni intestazione sarebbe nella stessa riga, e quindi se un'intestazione diventasse più alta, l'intera riga diventerebbe più alta.

Oggi non abbiamo una buona soluzione nei browser, ma è in arrivo. La funzione della griglia secondaria di CSS Grid Layout Level 2 abiliterà questo modello esatto. Sarai in grado di creare una griglia sul genitore e quindi scegliere selettivamente le righe e/o le colonne per utilizzare quella griglia, piuttosto che definire una nuova griglia sull'elemento child che è completamente indipendente da quella griglia.

Nota che gli esempi che seguono funzionano solo al momento della scrittura in Firefox Nightly. Il valore della grid-template-columns grid-template-rows è una nuova funzionalità e fa parte del livello 2 della specifica della griglia CSS. Per provare questa funzione, scarica una copia di Firefox Nightly.

Puoi vedere come funziona nelle immagini qui sotto. Nella prima immagine, ho creato tre tracce di riga sul genitore e ho attraversato la scheda su di esse. Con Firefox Grid Inspector che evidenzia la griglia, puoi vedere che le righe del genitore non sono correlate alle righe usate dai figli.

Un'immagine di una griglia a tre colonne con tracce di Firefox Grid Inspector sovrapposte.
L'ispezione della griglia con Firefox Grid Inspector mostra che gli elementi non vengono visualizzati nelle tracce del genitore. (Grande anteprima)

Se, invece di definire tre righe sul figlio, utilizzo il valore subgrid per grid-template-rows , la scheda ora utilizza quelle righe sul genitore. Puoi vedere come ora i due sono allineati e quindi anche le intestazioni e i piè di pagina si allineano:

Un'immagine di una griglia a tre colonne, tutti gli elementi all'interno delle carte allineati.
Usando la griglia secondaria, ogni parte della carta va nella propria traccia (anteprima grande)

Quello che stiamo facendo qui con subgrid non è un nuovo valore di display . L'elemento che è una griglia secondaria è esso stesso un contenitore della griglia, poiché abbiamo impostato display: grid su di esso. Gli elementi della griglia si comportano come fanno normalmente gli elementi della griglia. Questo è il layout della griglia normale, non diverso dalla griglia nidificata originale tranne per il fatto che (invece che l'elemento ha il proprio ridimensionamento della traccia di riga) utilizza le tracce del genitore.

 .cards { display: grid; gap: 20px; grid-template-columns: 1fr 1fr 1fr; grid-template-rows: repeat(2,auto 1fr auto); } article { grid-row-end: span 3; display: grid; grid-template-rows: subgrid; }

Questa è la cosa bella della sottogriglia; non c'è molto da imparare se sai già come utilizzare il layout della griglia. Puoi leggere il resto dei dettagli nel mio post precedente qui su Smashing Magazine, "CSS Grid Level 2: Here Comes Subgrid".

Ieri (23 maggio 2019 ), la sottogriglia è arrivata in Firefox Nightly, quindi abbiamo un'implementazione verificabile del valore della sottogriglia di grid-template-columns e grid-template-rows . Per favore, prendi una copia di Nightly e provalo. Con una copia di Nightly, puoi vedere l'ultimo esempio funzionante in questo CodePen:

Guarda il display con penna: la sottogriglia non è ciò che vogliamo di Rachel Andrew.

Guarda il display con penna: la sottogriglia non è ciò che vogliamo di Rachel Andrew.

Vedi se riesci a pensare ad altri casi d'uso che vengono risolti con la funzione della griglia secondaria, o forse cose che ritieni manchino. Sebbene una funzione sia disponibile solo in un browser notturno, è il momento in cui è possibile apportare modifiche alle specifiche se vengono rilevati problemi. Quindi, fai un favore al tuo futuro sviluppo del web e prova funzionalità come questa in modo da poter contribuire alla piattaforma web e migliorare le cose.

Se pensi di aver trovato un bug nell'implementazione di Firefox, puoi dare un'occhiata al bug di implementazione principale su Bugzilla che si collega a problemi correlati nella sezione Dipende da . Se non riesci a vedere il tuo problema, crea un test case il più semplice possibile e solleva il bug. Se ritieni che la griglia secondaria dovrebbe fare qualcosa per risolvere un caso d'uso, e questo è qualcosa non dettagliato nelle specifiche, puoi sollevare un problema sul GitHub del gruppo di lavoro CSS per un potenziale miglioramento.

Che dire del display: contents ?

Se hai seguito, potresti pensare che display: contents (come descritto nel precedente articolo su display ) potrebbe risolvere i problemi che la sottogriglia cerca di risolvere: quello di consentire ai bambini indiretti di partecipare a un layout di griglia. Non è così, e il nostro esempio di carte è un modo perfetto per dimostrare la differenza.

Se, invece di rendere la nostra scheda un layout a griglia con display: grid , rimuovessimo il riquadro usando display: contents content , otterremmo questo risultato in questo prossimo CodePen. (Prova a rimuovere il display: contents dalle regole per .card per vedere la differenza.)

Guarda il display con penna: la sottogriglia non è ciò che vogliamo di Rachel Andrew.

Guarda il display con penna: la sottogriglia non è ciò che vogliamo di Rachel Andrew.

In questo esempio, la casella della scheda è stata rimossa e quindi l'intestazione, il contenuto e il piè di pagina partecipano direttamente al layout della griglia e vengono posizionati automaticamente sulla griglia. Non era affatto quello che volevamo! Il valore del contents della visualizzazione sarà davvero utile una volta affrontati i problemi di accessibilità nei browser menzionati nel mio ultimo articolo, tuttavia risolve problemi diversi da quello che stiamo esplorando.

Altre letture ed esempi

Ho creato una serie di esempi e demo per aiutare tutti a capire la sottogriglia. Puoi provarli ai link seguenti:

  • Esempi di livello 2 della griglia CSS
  • Livello 2 della griglia CSS: ecco la sottogriglia
  • Griglie fino in fondo (Presentazione)
  • Documentazione MDN per la sottogriglia