Tutto ciò che devi sapere sui margini CSS

Pubblicato: 2022-03-10
Riassunto veloce ↬ I margini nei CSS sembrano abbastanza semplici a prima vista. Applicato a un elemento forma uno spazio attorno all'elemento, allontanando altri elementi. Tuttavia, c'è più margine di quanto potresti pensare.

Una delle prime cose che molti di noi hanno imparato quando abbiamo imparato i CSS, sono stati i dettagli delle varie parti di una scatola nei CSS, descritte come The CSS Box Model. Uno degli elementi nel Box Model è il margine, un'area trasparente attorno a una scatola, che spingerà gli altri elementi lontano dal contenuto della scatola. Le proprietà margin-top , margin-right , margin-bottom e margin-left sono state descritte subito nei CSS1, insieme alla scorciatoia margin per impostare tutte e quattro le proprietà contemporaneamente.

Un margine sembra essere una cosa abbastanza semplice, tuttavia, in questo articolo, daremo un'occhiata ad alcune delle cose che fanno inciampare le persone riguardo all'uso dei margini. In particolare, esamineremo come i margini interagiscono tra loro e come funziona effettivamente il collasso dei margini.

Il modello CSS Box

Come per tutti gli articoli su parti del CSS Box Model, dovremmo definire cosa intendiamo con questo e come il modello è stato chiarito attraverso le versioni di CSS. Il Box Model si riferisce al modo in cui le varie parti di una scatola - il contenuto, il riempimento, il bordo e il margine - sono disposte e interagiscono tra loro. In CSS1, il Box Model è stato dettagliato con il diagramma artistico ASCII mostrato nell'immagine sottostante.

ascii art disegno del modello a scatola
Rappresentazione del modello CSS Box in CSS1

Le quattro proprietà del margine per ciascun lato del riquadro e la scorciatoia del margin sono state tutte definite in CSS1.

La specifica CSS2.1 ha un'illustrazione per dimostrare il Box Model e definisce anche i termini che usiamo ancora per descrivere i vari box. La specifica descrive la casella del content box padding box border box e la margin box , ciascuna definita rispettivamente dai bordi del contenuto, dalla spaziatura interna, dal bordo e dal margine.

diagramma del CSS Box Model
Depection del CSS Box Model in CSS2

C'è ora una specifica del Modello Box di Livello 3 come Bozza di Lavoro. Questa specifica fa riferimento a CSS2 per le definizioni del Box Model e dei margini, quindi è la definizione CSS2 che useremo per la maggior parte di questo articolo.

Altro dopo il salto! Continua a leggere sotto ↓

Margine che crolla

La specifica CSS1, poiché definiva i margini, definiva anche il collasso dei margini verticali. Da allora questo comportamento al collasso è stato fonte di frustrazione legata ai margini. Il collasso del margine ha senso se si considera che in quei primi giorni i CSS venivano usati come linguaggio di formattazione per la documentazione. La compressione del margine significa che quando un'intestazione con un margine inferiore è seguita da un paragrafo con un margine superiore, non si ottiene un enorme divario tra quegli elementi.

Quando i margini crollano, si uniranno in modo che lo spazio tra i due elementi diventi il ​​più grande dei due margini. Il margine più piccolo finisce essenzialmente all'interno di quello più grande.

I margini crollano nelle seguenti situazioni:

  • Fratelli adiacenti
  • Scatole completamente vuote
  • Elemento padre e primo o ultimo figlio

Diamo un'occhiata a ciascuno di questi scenari a turno, prima di esaminare le cose che impediscono ai margini di crollare in questi scenari.

Fratelli adiacenti

La mia descrizione iniziale del collasso dei margini è una dimostrazione di come i margini tra fratelli adiacenti collassano. A parte le situazioni menzionate di seguito, se hai due elementi visualizzati uno dopo l'altro nel flusso normale, il margine inferiore del primo elemento collasserà con il margine superiore dell'elemento successivo.

Nell'esempio CodePen riportato di seguito, sono presenti tre elementi div . Il primo ha un margine superiore e inferiore di 50 pixel. Il secondo ha un margine superiore e inferiore di 20px. Il terzo ha un margine superiore e inferiore di 3em. Il margine tra i primi due elementi è di 50 pixel, poiché il margine superiore più piccolo è combinato con il margine inferiore più grande. Il margine tra i secondi due elementi in 3em, poiché 3em è maggiore dei 20 pixel nella parte inferiore del secondo elemento.

Vedi la penna [Margini: fratelli adiacenti](https://codepen.io/rachelandrew/pen/OevMPo) di Rachel Andrew.

Vedi i margini della penna: fratelli adiacenti di Rachel Andrew.

Scatole completamente vuote

Se una casella è vuota, i suoi margini superiore e inferiore potrebbero crollare l'uno con l'altro. Nell'esempio CodePen seguente, l'elemento con una classe vuota ha un margine superiore e inferiore di 50 pixel, tuttavia lo spazio tra il primo e il terzo elemento non è 100 pixel, ma 50. Ciò è dovuto alla compressione dei due margini. L'aggiunta di qualsiasi cosa a quella casella (anche il riempimento) farà sì che i margini superiore e inferiore vengano utilizzati e non collassano.

Vedi la penna [Margini: scatole vuote](https://codepen.io/rachelandrew/pen/JQLGMr) di Rachel Andrew.

Vedi i margini della penna: scatole vuote di Rachel Andrew.

Elemento genitore e primo o ultimo figlio

Questo è lo scenario di collasso dei margini che cattura le persone più spesso, poiché non sembra particolarmente intuitivo. Nel seguente CodePen, ho un div con una classe di wrapper e ho assegnato a quel div un outline in rosso in modo che tu possa vedere dove si trova. I tre elementi figlio hanno tutti un margine di 50 pixel. Tuttavia, il primo e l'ultimo articolo sono a filo con i bordi dell'involucro; non c'è un margine di 50 pixel tra l'elemento e il wrapper.

See the Pen [Margins: margin on first and last child](https://codepen.io/rachelandrew/pen/BgrKGp) di Rachel Andrew.

Vedi i margini della penna: margine sul primo e sull'ultimo figlio di Rachel Andrew.

Questo perché il margine sul figlio collassa con qualsiasi margine sul genitore finendo così all'esterno del genitore. Puoi vederlo se ispezioni il primo figlio usando DevTools. L'area gialla evidenziata è il margine.

L'elemento con un margine evidenziato in giallo esterno al genitore
DepvTools può aiutarti a vedere dove finisce il tuo margine

Solo i margini di blocco crollano

L'ultimo esempio evidenzia anche qualcosa sul collasso del margine. In CSS2, solo i margini verticali sono specificati per la compressione, ovvero i margini superiore e inferiore di un elemento se ci si trova in una modalità di scrittura orizzontale. Quindi i margini sinistro e destro sopra non collassano e finiscono fuori dal wrapper.

Nota : vale la pena ricordare che i margini si riducono solo nella direzione del blocco, ad esempio tra i paragrafi.

Cose che impediscono il crollo del margine

I margini non crollano mai se un elemento ha un posizionamento assoluto o è flottante. Tuttavia, supponendo che ti sia imbattuto in uno dei punti in cui i margini crollano delineati sopra, come puoi impedire che questi margini collassano?

La prima cosa che smette di crollare sono le situazioni in cui c'è qualcosa tra gli elementi in questione.

Ad esempio, una casella completamente vuota di contenuto non comprimerà i margini superiore e inferiore se ha un bordo o un riempimento applicato. Nell'esempio seguente ho aggiunto 1px di riempimento alla scatola. Ora c'è un margine di 50 pixel sopra e sotto il riquadro.

Vedi la penna [Margini: le scatole vuote con imbottitura non crollano](https://codepen.io/rachelandrew/pen/gNeMpg) di Rachel Andrew.

Vedi i margini della penna: le scatole vuote con imbottitura non crollano di Rachel Andrew.

Questo ha una logica dietro, se la scatola è completamente vuota senza bordo o riempimento, è essenzialmente invisibile. Potrebbe essere un elemento di paragrafo vuoto inserito nel markup dal tuo CMS. Se il tuo CMS aggiungeva elementi di paragrafo ridondanti, probabilmente non vorresti che causassero grandi divari tra gli altri paragrafi a causa del rispetto dei loro margini. Aggiungi qualsiasi cosa alla scatola e otterrai quegli spazi vuoti.

Un comportamento simile può essere visto con i margini sul primo o sull'ultimo figlio che collassano attraverso il genitore. Se aggiungiamo un bordo al genitore, i margini sui figli rimangono all'interno.

Vedi la penna [Margini: il margine sul primo e sull'ultimo figlio non crolla se il genitore ha un bordo](https://codepen.io/rachelandrew/pen/vqRKKX) di Rachel Andrew.

Vedi i margini della penna: il margine sul primo e sull'ultimo figlio non crolla se il genitore ha un bordo di Rachel Andrew.

Ancora una volta, c'è una logica nel comportamento. Se hai elementi di wrapping per scopi semantici che non vengono visualizzati visivamente, probabilmente non vuoi che introducano grandi lacune nella visualizzazione. Questo aveva molto senso quando il web era principalmente testo. È meno utile come comportamento quando utilizziamo gli elementi per tracciare un progetto.

Creazione di un contesto di formattazione a blocchi

Un nuovo Block Formatting Context (BFC) impedirà anche la compressione del margine attraverso l'elemento contenitore. Se osserviamo di nuovo l'esempio del primo e dell'ultimo figlio, che finiscono con i margini all'esterno del wrapper, e diamo al wrapper la display: flow-root , creando così un nuovo BFC, i margini rimangono all'interno.

Vedi la penna [Margini: un nuovo contesto di formattazione a blocchi contiene margini](https://codepen.io/rachelandrew/pen/VJXjEp) di Rachel Andrew.

Vedi i margini della penna: un nuovo contesto di formattazione a blocchi contiene margini di Rachel Andrew.

Per saperne di più su display: flow-root , leggi il mio articolo "Capire il layout CSS e il contesto di formattazione dei blocchi". La modifica del valore della proprietà di overflow su auto avrà lo stesso effetto, poiché ciò crea anche un nuovo BFC, sebbene in alcuni scenari possa anche creare barre di scorrimento che non si desideravano.

Contenitori Flex E Griglia

I contenitori Flex e Grid stabiliscono contesti di formattazione Flex e Grid per i loro figli, in modo che abbiano un comportamento diverso per bloccare il layout. Una di queste differenze è che i margini non crollano:

“Un contenitore flessibile stabilisce un nuovo contesto di formattazione flessibile per i suoi contenuti. Questo equivale a stabilire un contesto di formattazione a blocchi, tranne per il fatto che viene utilizzato il layout flessibile anziché il layout a blocchi. Ad esempio, i float non si intromettono nel contenitore flessibile e i margini del contenitore flessibile non collassano con i margini del suo contenuto".

— Flexbox livello 1

Se prendiamo l'esempio sopra e trasformiamo il wrapper in un contenitore flessibile, visualizzando gli elementi con flex-direction: column , puoi vedere che i margini sono ora contenuti dal wrapper. Inoltre, i margini tra elementi flessibili adiacenti non si contraggono l'uno con l'altro, quindi ci ritroviamo con 100 pixel tra elementi flessibili, il totale dei 50 pixel nella parte superiore e inferiore degli elementi.

Vedi la penna [Margini: i margini sugli elementi flessibili non crollano](https://codepen.io/rachelandrew/pen/mZxreL) di Rachel Andrew.

Vedi i margini della penna: i margini sugli oggetti flessibili non crollano di Rachel Andrew.

Strategie di margine per il tuo sito

A causa del crollo dei margini, è una buona idea trovare un modo coerente per gestire i margini nel tuo sito. La cosa più semplice da fare è definire solo i margini nella parte superiore o inferiore degli elementi. In questo modo, non dovresti incappare in problemi di collasso del margine troppo spesso poiché il lato con un margine sarà sempre adiacente a un lato senza margine.

Nota : Harry Roberts ha un post eccellente che descrive in dettaglio i motivi per cui impostare i margini solo in una direzione è una buona idea, e non solo per risolvere problemi di collasso dei margini.

Questa soluzione non risolve i problemi che potresti incontrare con i margini sui bambini che crollano a causa dei loro genitori. Quel particolare problema tende ad essere meno comune e sapere perché sta accadendo può aiutarti a trovare una soluzione. Una soluzione ideale è fornire i componenti che lo richiedono la display: flow-root , come ripiego per i browser più vecchi è possibile utilizzare overflow per creare un BFC, trasformare il genitore in un contenitore flessibile o persino introdurre un singolo pixel di riempimento. Non dimenticare che puoi utilizzare le query di funzionalità per rilevare il supporto per la display: flow-root modo che solo i vecchi browser ottengano una correzione meno ottimale.

La maggior parte delle volte, trovo che sapere perché i margini crollano (o no) sia la cosa fondamentale. È quindi possibile capire caso per caso come affrontarlo. Qualunque cosa tu scelga, assicurati di condividere tali informazioni con il tuo team. Abbastanza spesso il collasso dei margini è un po' misterioso, quindi il motivo per fare cose per contrastarlo potrebbe non essere ovvio! Un commento nel tuo codice aiuta molto: potresti persino collegarti a questo articolo e aiutare a condividere la conoscenza del crollo dei margini.

Ho pensato di completare questo articolo con alcune altre informazioni relative ai margini.

Margini percentuali

Quando usi una percentuale in CSS, deve essere una percentuale di qualcosa. I margini (e il riempimento) impostati utilizzando le percentuali saranno sempre una percentuale della dimensione inline (larghezza in modalità di scrittura orizzontale) del genitore. Ciò significa che avrai un riempimento di dimensioni uguali attorno all'elemento quando utilizzi le percentuali.

Nell'esempio CodePen di seguito, ho un wrapper largo 200 pixel, all'interno c'è una scatola che ha un margine del 10%, il margine è di 20 pixel su tutti i lati, ovvero il 10% di 200.

Vedi la penna [Margini: margini percentuali](https://codepen.io/rachelandrew/pen/orqzrP) di Rachel Andrew.

Vedi i margini della penna: margini percentuali di Rachel Andrew.

Margini in un mondo relativo al flusso

Abbiamo parlato di margini verticali in tutto questo articolo, tuttavia, i CSS moderni tendono a pensare alle cose in un modo relativo al flusso piuttosto che fisico. Pertanto, quando si parla di margini verticali, si parla proprio di margini nella dimensione del blocco. Quei margini saranno in alto e in basso se ci troviamo in una modalità di scrittura orizzontale, ma sarebbero a destra ea sinistra in una modalità di scrittura verticale scritta da sinistra a destra.

Una volta che si lavora con direzioni logiche e relative al flusso, diventa più facile parlare di inizio e fine blocco, piuttosto che di alto e basso. Per rendere tutto più semplice, CSS ha introdotto la specifica Proprietà e valori logici. Questo mappa le proprietà relative del flusso su quelle fisiche.

Per i margini, questo ci fornisce le seguenti mappature (se stiamo lavorando in inglese o in qualsiasi altra modalità di scrittura orizzontale con una direzione del testo da sinistra a destra).

  • margin-top = margin-block-start
  • margin-right = margin-inline-end
  • margin-bottom = margin-block-end
  • margin-left = margin-inline-start

Abbiamo anche due nuove abbreviazioni che consentono di impostare entrambi i blocchi contemporaneamente o entrambi in linea.

  • margin-block
  • margin-inline

Nel prossimo esempio di CodePen, ho utilizzato queste parole chiave relative al flusso e quindi ho modificato la modalità di scrittura della casella, puoi vedere come i margini seguono la direzione del testo anziché essere legati a in alto, a destra, in basso e a sinistra fisici.

Vedi la penna [Margins: flow relativi margins](https://codepen.io/rachelandrew/pen/BgrQRj) di Rachel Andrew.

Vedi i margini della penna: margini relativi di flusso di Rachel Andrew.

Puoi leggere di più sulle proprietà e i valori logici su MDN o nel mio articolo "Capire i valori e le proprietà logiche" qui su Smashing Magazine.

Per concludere

Ora sai la maggior parte di ciò che c'è da sapere sui margini! In breve:

  • Il crollo del margine è una cosa. Capire perché succede e quando non succede ti aiuterà a risolvere tutti i problemi che potrebbe causare.
  • L'impostazione dei margini in una direzione risolve solo molti mal di testa relativi ai margini.
  • Come con qualsiasi cosa in CSS, condividi con il tuo team le decisioni che prendi e commenta il tuo codice.
  • Pensare alle dimensioni del blocco e inline piuttosto che alle dimensioni fisiche in alto, a destra, in basso e a sinistra ti aiuterà mentre il web si muove verso l'essere indipendente dalla modalità di scrittura.