Scavare nella proprietà di visualizzazione: i due valori di visualizzazione
Pubblicato: 2022-03-10display
CSS, un cavallo di battaglia di una proprietà che non riceve molta attenzione. Rachel Andrew dà un'occhiata migliore in una breve serie. Un layout flex o grid inizia con la dichiarazione di display: flex
o display: grid
. Questi metodi di layout sono valori della proprietà di display
CSS. Tendiamo a non parlare molto di questa proprietà da sola, concentrandoci invece sui valori di flex
o grid
, tuttavia, ci sono alcune cose interessanti da capire sul display
e su come viene definito che ti semplificheranno la vita mentre lo usi CSS per il layout.
In questo articolo, il primo di una breve serie, darò un'occhiata al modo in cui i valori di display
sono definiti nella specifica di livello 3. Questa è una modifica al modo in cui abbiamo definito la display
nelle versioni precedenti di CSS. Anche se all'inizio può sembrare insolito per quelli di noi che fanno CSS da molti anni, penso che questi cambiamenti aiutino davvero a spiegare cosa sta succedendo quando cambiamo il valore di display
su un elemento.
Blocco ed elementi in linea
Una delle prime cose che insegniamo alle persone che non conoscono i CSS sono i concetti di blocco e di elementi inline. Spiegheremo che alcuni elementi della pagina sono display: block
e hanno determinate caratteristiche per questo. Si estendono nella direzione in linea, occupando tutto lo spazio a loro disposizione. Si rompono su una nuova linea; possiamo dare loro larghezza, altezza, margine e riempimento, e queste proprietà allontaneranno altri elementi della pagina da loro.
Sappiamo anche che alcuni elementi sono display: inline
. Gli elementi in linea sono come le parole in una frase; non si interrompono su una nuova riga, ma riservano invece un carattere di spazio bianco tra di loro. Se aggiungi margini e riempimento, questo verrà visualizzato ma non spingerà via altri elementi.
Il comportamento degli elementi block e inline è fondamentale per CSS e il fatto che un documento HTML correttamente contrassegnato sarà leggibile per impostazione predefinita. Questo layout è indicato come "Block and Inline Layout" o "Normal Flow" perché questo è il modo in cui gli elementi si dispongono se non facciamo nient'altro a loro.
Valori interni ed esterni di display
Comprendiamo gli elementi block e inline, ma cosa succede se facciamo display: grid
? È qualcosa di completamente diverso? Se osserviamo un componente su cui abbiamo specificato display: grid
, in termini di elemento padre nel layout si comporta come un elemento a block level
. L'elemento si estenderà e occuperà tutto lo spazio disponibile nella dimensione in linea, inizierà su una nuova linea. Si comporta proprio come un elemento di block
in termini di come si comporta insieme al resto del layout. Non abbiamo detto display: block
però, o no?
Si scopre che abbiamo. Nel Livello 3 della specifica Display, il valore di display
è definito come due parole chiave. Queste parole chiave definiscono il valore esterno di visualizzazione, che sarà inline
o block
e quindi definiscono come si comporta l'elemento nel layout insieme ad altri elementi. Definiscono anche il valore interno dell'elemento o come si comportano i figli diretti di quell'elemento.
Ciò significa che quando dici display: grid
, in realtà stai dicendo display: block grid
. Stai chiedendo un contenitore di griglia a livello di blocco. Un elemento che avrà tutti gli attributi del blocco: puoi assegnargli altezza e larghezza, margine e riempimento e si allungherà per riempire il contenitore. Ai figli di quel contenitore, tuttavia, è stato assegnato il valore interno della grid
in modo che diventino elementi della griglia. Il modo in cui questi elementi della griglia si comportano è definito nella specifica della griglia CSS: le specifiche di display
ci danno un modo per dire al browser che questo è il metodo di layout che vogliamo usare.
Penso che questo modo di pensare al display
sia incredibilmente utile; spiega direttamente cosa stiamo facendo con vari metodi di layout. Se dovessi specificare display: inline flex
, cosa ti aspetteresti? Si spera che una scatola che si comporti come un elemento in linea, con figli che sono elementi flessibili.
Ci sono alcune altre cose ben spiegate pensando alla display
in questo nuovo modo e darò un'occhiata ad alcune di queste nel resto di questo articolo.
Stiamo sempre tornando al flusso normale
Quando si pensa a queste proprietà di visualizzazione interne ed esterne, può essere utile considerare cosa succede se non si scherza affatto con il valore della visualizzazione. Se scrivi del codice HTML e lo visualizzi in un browser, ciò che ottieni è Block and Inline Layout o Normal Flow. Gli elementi vengono visualizzati come elementi di block
o inline
.
L'esempio seguente contiene del markup che ho trasformato in un oggetto multimediale, facendo in modo che il div
display: flex
(i due figli diretti) ora diventano elementi flessibili, quindi l'immagine è ora in fila con il contenuto. Se vedi nel contenuto, tuttavia, c'è un'intestazione e un paragrafo che vengono nuovamente visualizzati nel flusso normale. I figli diretti dell'oggetto media sono diventati oggetti flessibili; i loro figli tornano al flusso normale a meno che non modifichiamo il valore di visualizzazione sull'elemento flessibile. Il contenitore flessibile stesso è una scatola a blocchi, come puoi vedere dal fatto che il bordo si estende fino al bordo del suo genitore.
Se lavori con questo processo, il fatto che gli elementi sulla tua pagina si disporranno da soli con questo layout di flusso normale leggibile, piuttosto che combatterlo e cercare di posizionare tutto, CSS è molto più semplice. È anche meno probabile che si verifichino problemi di accessibilità, poiché si lavora con l'ordine del documento, che è esattamente ciò che sta facendo uno screen reader o una persona che sfoglia il documento.
Spiegare flow-root
e inline-block
È probabile che il valore di inline-block
sia familiare anche a molti di noi che fanno CSS da un po' di tempo. Questo valore è un modo per ottenere parte del comportamento del blocco su un elemento inline
. Ad esempio, un elemento inline-block
può avere una larghezza e un'altezza. Un elemento con display: inline-block
si comporta anche in modo interessante in quanto crea un B lock F ormatting C ontent (BFC).
Un BFC fa alcune cose utili in termini di layout, ad esempio contiene float. Per leggere i contesti di formattazione a blocchi in modo più dettagliato, vedere il mio precedente articolo "Capire il layout CSS e il contesto di formattazione a blocchi". Quindi dicendo display: inline-block
ti dà una casella inline che stabilisce anche un BFC.
Come scoprirai (se leggi l'articolo sopra menzionato sul contesto di formattazione dei blocchi), esiste un nuovo valore di visualizzazione che crea anche esplicitamente un BFC. Questo è il valore di flow-root
. Questo valore crea un BFC su un blocco, anziché un elemento inline.
-
display: inline-block
ti dà un BFC su una scatola in linea. -
display: flow-root
ti dà un BFC su una block box.
Probabilmente ora stai pensando che è tutto un po' confuso: perché abbiamo due parole chiave completamente diverse qui e cosa è successo alla sintassi a due valori di cui stavamo parlando prima? Questo porta chiaramente alla prossima cosa che devo spiegare su display
, cioè il fatto che CSS ha una storia che dobbiamo affrontare in termini di proprietà display
.
Valori legacy di visualizzazione
La specifica CSS2 ha dettagliato i seguenti valori per la proprietà display
:
-
inline
-
block
-
inline-block
-
list-item
-
none
-
table
-
inline-table
Sono state anche definite le varie proprietà interne della tabella come table-cell
cui non ci occuperemo in questo articolo.
Abbiamo quindi aggiunto a questi alcuni valori per la visualizzazione, per supportare il layout flex e grid:
-
grid
-
inline-grid
-
flex
-
inline-flex
Nota : la specifica definisce anche ruby
e inline-ruby
per supportare Ruby Text di cui puoi leggere nelle specifiche Ruby.
Questi sono tutti valori singoli per la proprietà display
, definiti prima dell'aggiornamento della specifica per spiegare CSS Layout in questo modo. Qualcosa di molto importante nei CSS è il fatto che non andiamo in giro a rompere il web; non possiamo semplicemente cambiare le cose . Non possiamo improvvisamente decidere che tutti dovrebbero usare questa nuova sintassi a due valori e quindi ogni sito Web mai creato che ha utilizzato la sintassi a valore singolo si interromperà a meno che uno sviluppatore non torni indietro e lo aggiusti!
Mentre pensi a questo problema, potresti goderti questo elenco di errori nella progettazione dei CSS che in molti casi sono meno errori come cose che sono state progettate senza una sfera di cristallo per vedere nel futuro! Tuttavia, il fatto è che non possiamo rompere il Web, motivo per cui abbiamo questa situazione in cui in questo momento i browser supportano un insieme di valori singoli per la visualizzazione e la specifica si sta spostando su due valori per la visualizzazione.
Il modo per aggirare questo problema è specificare i valori legacy e brevi per la visualizzazione, che include tutti questi valori singoli. Ciò significa che è possibile definire una mappatura tra valori singoli e nuovi valori di due parole chiave. Il che ci fornisce la seguente tabella di valori:
Valore unico | Valori di due parole chiave | Descrizione |
---|---|---|
block | block flow | Block box con flusso normale interno |
flow-root | block flow-root | Block box che definisce un BFC |
inline | inline flow | Scatola in linea con flusso normale interno |
inline-block | inline flow-root | Casella in linea che definisce un BFC |
list-item | block flow list-item | Block box con flusso normale interno e box marker aggiuntivo |
flex | block flex | Block box con disposizione interna flessibile |
inline-flex | inline flex | Scatola in linea con disposizione interna flessibile |
grid | block grid | Block box con layout a griglia interna |
inline-grid | inline grid | Scatola in linea con layout a griglia interna |
table | block table | Block box con disposizione interna del tavolo |
inline-table | inline table | Scatola in linea con disposizione interna del tavolo |
Per spiegare come funziona, possiamo pensare a un contenitore a griglia. Nel mondo a due valori, creeremmo un contenitore di griglia a livello di blocco con:
.container { display: block grid; }
Tuttavia, la parola chiave legacy significa che quanto segue fa la stessa cosa:
.container { display: grid; }
Se, invece, volessimo un contenitore grid inline, nel mondo a due valori utilizzeremmo:
.container { display: inline grid; }
E se si utilizzano i valori legacy:
.container { display: inline-grid; }
Ora possiamo tornare al punto in cui è iniziata questa conversazione e guardare display: inline-block
. Osservando la tabella, puoi vedere che questo è definito nel mondo a due valori come display: inline flow-root
. Ora corrisponde display: flow-root
che in un mondo a due valori sarebbe display: block flow-root
. Un po' di riordino e chiarimento su come vengono definite queste cose. Un refactoring dei CSS, se vuoi.
Supporto del browser per la sintassi a due valori
Al momento, i browser non supportano la sintassi a due valori per la proprietà display
. Il bug di implementazione per Firefox può essere trovato qui. L'implementazione, quando si verifica, comporterebbe essenzialmente l'aliasing dei valori legacy nelle versioni a due valori. È probabile che passerà del tempo, quindi, prima che tu possa effettivamente utilizzare queste versioni a due valori nel tuo codice. Tuttavia, non è proprio questo il punto di questo articolo. Invece, penso che guardare i valori di visualizzazione alla luce del modello a due valori aiuti a spiegare molto di ciò che sta accadendo.
Quando definisci il layout su un box in CSS, stai definendo cosa succede a questo box in termini di come si comporta in relazione a tutti gli altri box nel layout . Stai anche definendo come si comportano i figli di quella scatola. Puoi pensare in questo modo molto prima di poter dichiarare esplicitamente i valori come due cose separate, poiché le parole chiave legacy sono associate a quei valori e ti aiuteranno a capire cosa succede quando modifichi il valore di display
.