Scavare nella proprietà di visualizzazione: generazione di scatole
Pubblicato: 2022-03-10display
nei CSS, questa volta Rachel Andrew dà un'occhiata ai valori che controllano la generazione di box, per quelle volte in cui non si vuole generare un box per niente. Questo è il secondo di una breve serie di articoli sulla proprietà display
nei CSS. Puoi leggere l'articolo iniziale della serie su "The Two Values Of Display". La specifica del display
è una specifica molto utile da comprendere in quanto è alla base di tutti i diversi metodi di layout che abbiamo.
Sebbene molti dei valori di display
abbiano le proprie specifiche, molti termini e idee sono dettagliati in display
. Ciò significa che la comprensione di questa specifica aiuta a comprendere le specifiche che essenzialmente descrivono in dettaglio i valori di display
. In questo articolo, darò un'occhiata ai valori di generazione della casella di display
: none
e contents
.
Tutto è una scatola
In CSS tutto genera scatole. Una pagina Web è essenzialmente un insieme di blocchi e caselle inline, qualcosa che puoi capire molto bene se apri DevTools nel tuo browser preferito e inizi a selezionare gli elementi sulla pagina. Puoi vedere le caselle che compongono il layout e come vengono applicati i loro margini, riempimento e bordi.
Generazione di scatole di controllo
I valori none
e contents
di display
determinano se le caselle debbano apparire. Se hai elementi nel tuo markup e non vuoi che generino un box in CSS, allora devi in qualche modo sopprimere la generazione del box. Ci sono due possibili cose che potresti voler fare. Quali sono:
- Impedisci la generazione di una scatola e di tutti i suoi figli.
- Impedisci la generazione di una scatola ma mostra comunque i bambini.
Possiamo dare un'occhiata a ciascuno di questi scenari a turno.
display: nessuno
Il valore none
di display
è il modo in cui impediamo la generazione di una scatola e tutti i figli di quella scatola. Si comporta come se l'elemento non fosse affatto presente. Pertanto, è utile nelle situazioni in cui si intende nascondere completamente quel contenuto, magari perché verrà rivelato successivamente dopo l'attivazione di un collegamento.
Se ho un esempio con un paragrafo, un elenco non ordinato e un altro paragrafo, puoi vedere che gli elementi vengono visualizzati nel flusso normale. L' ul
ha uno sfondo e un bordo applicati, oltre a un'imbottitura.
Se aggiungo display: none
ul
scompare dalla visualizzazione, portando con sé i figli ul
più lo sfondo e il bordo.
Se utilizzi display: none
nasconde il contenuto a tutti gli utenti del sito. Ciò include gli utenti di screen reader. Pertanto, dovresti usarlo solo se la tua intenzione è che la scatola e tutto ciò che contiene siano completamente nascosti a tutti.
Ci sono situazioni in cui potresti voler aggiungere ulteriori informazioni per gli utenti di tecnologie assistive come i lettori di schermo ma nasconderle per altri utenti; in questi casi, è necessario utilizzare una tecnica diversa. Alcuni ottimi suggerimenti sono dati da Scott O'Hara nel suo articolo “Inclusively Hidden”.
Utilizzo del display: none
è quindi abbastanza semplice. Usalo in una situazione in cui vuoi che una scatola e il contenuto scompaiano dal display, dall'albero della scatola e dall'albero dell'accessibilità (come se non fosse mai stato lì in primo luogo).
visualizzazione: contenuto
Per il secondo scenario, dobbiamo guardare a un valore di visualizzazione molto più nuovo. Il valore display: contents
rimuoverà la casella a cui è applicato dall'albero della scatola nello stesso modo in cui display: none
lo fa, ma lascia i bambini al loro posto. Ciò causa alcuni comportamenti utili in termini di cose che possiamo quindi fare nei nostri layout. Diamo un'occhiata a un semplice esempio e poi esploriamo ulteriormente.
Sto usando lo stesso esempio di prima, ma questa volta ho usato display: contents
su ul
. Gli elementi dell'elenco sono ora visibili, tuttavia, non hanno sfondo e bordi e si comportano come se avessi aggiunto elementi li
alla pagina senza racchiudere ul
.
Il motivo per cui è utile rimuovere una casella e tenere i bambini è dovuto al modo in cui si comportano gli altri valori di display
. Quando cambiamo il valore di display
lo facciamo su una casella e sui figli diretti di quella casella, come ho descritto nell'ultimo articolo. Se aggiungo display: flex
alle regole CSS per un elemento, quell'elemento diventa una casella a livello di blocco e i figli diretti diventano elementi flessibili. I figli di questi elementi flessibili tornano al flusso normale (non fanno parte del layout flessibile).
Puoi vedere questo comportamento nel prossimo esempio. Qui ho un elemento contenitore impostato per visualizzare flex, ha quattro figli diretti, tre elementi div e un ul
. L' ul
ha due voci di elenco. I bambini diretti partecipano tutti al layout flessibile e si dispongono come elementi flessibili. Gli elementi dell'elenco non sono figli diretti e quindi vengono visualizzati come elementi dell'elenco all'interno della casella ul
.
Se prendiamo questo esempio e aggiungiamo display: contents
a ul
, la casella viene rimossa dal display visivo e ora i bambini partecipano al layout flessibile. Puoi vedere che non diventano bambini diretti. Non vengono selezionati dal selettore universale figlio diretto ( .wrapper > *
) nel modo in cui lo sono gli elementi div e ul
e mantengono lo sfondo loro assegnato. Tutto quello che è successo è che la scatola ul
contenente è stata rimossa, tutto il resto procede normalmente.
Ciò ha implicazioni potenzialmente molto utili se consideriamo elementi in HTML che sono importanti per l'accessibilità ei dati semantici, ma che generano un riquadro aggiuntivo che potrebbe impedirci di disporre il contenuto con layout flessibile o griglia.
Questo non è un "ripristino" CSS
Potresti aver notato come un effetto collaterale dell'utilizzo del display: contents
è che il margine e il riempimento sull'elemento vengono rimossi. Questo perché sono correlati alla scatola, parte del CSS Box Model. Questo potrebbe farti pensare che display: contents
sia un buon modo per liberarti rapidamente del padding e del margine su un elemento.
Questo è un uso che Adrian Roselli ha individuato in natura; era abbastanza preoccupato da scrivere un post dettagliato in cui spiegava i problemi di farlo - " display: contents
non sono un ripristino CSS". Alcuni dei problemi che solleva sono dovuti a uno sfortunato problema di accessibilità nei browser attualmente con display: contenuti di cui parleremo di seguito. Tuttavia, anche una volta risolti questi problemi, rimuovere un elemento dal bosso semplicemente per liberarti del margine e del riempimento è alquanto estremo.
Se non altro, sarebbe problematico per la futura manutenzione del sito, un futuro sviluppatore potrebbe chiedersi perché non sembra essere in grado di applicare nulla a questa scatola misteriosa, mancando il fatto che sia stata rimossa! Se hai bisogno che il margine e il padding siano 0
, fai un favore a te stesso futuro e impostali su 0
in un modo consacrato. Riserva l'uso del display: contents
per quei casi speciali in cui vuoi davvero rimuovere la scatola.
Vale anche la pena notare la differenza tra display: contents
e griglia secondaria CSS Grid Layout. Dove display: contents
rimuove completamente il riquadro, lo sfondo e il bordo dal display, trasformando un elemento della griglia in una griglia secondaria manterrebbe lo stile del riquadro su quell'elemento e passerebbe semplicemente attraverso il ridimensionamento della traccia in modo che gli elementi nidificati possano utilizzare la stessa griglia. Scopri di più nel mio articolo "CSS Grid Level 2: Here Comes Subgrid".
Problemi di accessibilità e visualizzazione: contenuti
Un problema serio attualmente fa la display: contents
non utili proprio per la cosa per cui sarebbero più utili. I casi ovvi per la display: contents
sono quei casi in cui sono necessarie caselle aggiuntive per aggiungere markup che renda i tuoi contenuti più facilmente comprensibili da coloro che utilizzano lettori di schermo o altri dispositivi di assistenza.
L'elemento ul
della nostra lista nel primo display: contents
content CodePen è un esempio perfetto. È possibile ottenere lo stesso risultato visivo appiattendo il markup e non utilizzando affatto un elenco. Tuttavia, se il contenuto fosse semanticamente un elenco, sarebbe meglio compreso e letto da uno screen reader come un elenco, dovrebbe essere contrassegnato come tale.
Se poi vuoi che gli elementi figlio facciano parte di un layout flessibile o griglia, proprio come se la scatola di ul
non fosse lì, dovresti essere in grado di usare display: contents
per eliminare con la magia la scatola e renderlo tale, ma lascia la semantica in atto. La specifica dice che questo dovrebbe essere il caso,
“La proprietàdisplay
non ha alcun effetto sulla semantica di un elemento: questi sono definiti dal linguaggio del documento e non sono influenzati dai CSS. A parte il valore none, che influisce anche sull'output sonoro/vocale e sull'interattività di un elemento e dei suoi discendenti, la proprietàdisplay
influisce solo sul layout visivo: il suo scopo è consentire ai progettisti la libertà di modificare il comportamento del layout di un elemento senza influire sul sottostante semantica del documento”.
Come abbiamo già discusso, il valore none
nasconde l'elemento agli screen reader, tuttavia, altri valori di display
sono puramente lì per permetterci di cambiare il modo in cui le cose vengono visualizzate visivamente . Non dovrebbero toccare la semantica del documento.
Per questo motivo, molti di noi hanno colto di sorpresa quella display: contents
stavano infatti rimuovendo l'elemento dall'albero dell'accessibilità nei due browser (Chrome e Firefox) che lo avevano implementato. Modificando quindi la semantica del documento, facendo in modo che uno screen reader non sapesse che un elenco era un elenco una volta che l' ul
era stato rimosso utilizzando display: contents
. Questo è un bug del browser, e per di più serio.
L'anno scorso, Hidde de Vries ha scritto questo problema nel suo post "More Accessible Markup with display:contents
" e ha sollevato utilmente problemi contro i vari browser al fine di aumentare la consapevolezza e farli lavorare su una soluzione. Firefox ha parzialmente risolto il problema, sebbene esistano ancora problemi con alcuni elementi come il pulsante. Il problema viene attivamente risolto in Chrome. C'è anche un problema per WebKit. Ti incoraggerei a contrassegnare questi bug se hai casi d'uso per la visualizzazione: contenuti che sarebbero interessati dai problemi.
Fino a quando questi problemi non vengono risolti e le versioni del browser che hanno mostrato il problema non vengono più utilizzate, è necessario prestare molta attenzione quando si utilizza la visualizzazione: contenuti su tutto ciò che trasmette informazioni semantiche e deve essere esposto alla tecnologia assistiva. Come afferma Adrian Roselli,
"Per ora, utilizza solo display: content se hai intenzione di testare con la tecnologia assistiva e puoi confermare che i risultati funzionano per gli utenti".
Ci sono posti dove puoi tranquillamente usare display: contents
senza questa preoccupazione. Uno sarebbe se fosse necessario aggiungere ulteriore markup per creare fallback per la griglia di layout flessibili nei browser meno recenti. Browser che supportano la display: contents
supportano anche grid e flexbox, quindi è possibile display: contents
eliminano gli elementi div
ridondanti aggiunti. Nell'esempio seguente, ho creato una griglia basata su float, completa di wrapper di riga.
Quindi utilizzo display: contents
per rimuovere i wrapper di riga per consentire a tutti gli elementi di diventare elementi della griglia e quindi essere in grado di far parte del layout della griglia. Questo potrebbe darti uno strumento aggiuntivo durante la creazione di fallback per layout avanzati in quanto se è necessario aggiungere ulteriore markup, è possibile rimuoverlo con display: content quando si esegue la griglia o il layout flessibile. Non credo che questo utilizzo dovrebbe causare problemi, anche se se qualcuno ha informazioni sull'accessibilità migliori di me e può segnalare un problema, lo faccia nei commenti.
Avvolgendo
Questo articolo ha esaminato i valori di generazione della casella della proprietà display
. Spero che tu ora comprenda il diverso comportamento di display: none
— che rimuove completamente una scatola e tutti i bambini, e display: contents
che rimuove solo la scatola stessa. Dovresti anche comprendere i potenziali problemi dell'utilizzo di questi metodi per quanto riguarda l'accessibilità.