CSS / padding e margin: spaziatura, larghezza e collasso dei margini

In CSS, padding è lo spazio tra il contenuto e il bordo, mentre margin è al di fuori del bordo. Usa il padding per espandere l'interno di un elemento, incluso il suo sfondo, e il margin per regolare la sua separazione dagli elementi circostanti. La larghezza risultante dipende da box-sizing, e i margini verticali idonei possono collassare invece di semplicemente sommarsi.

Differenze tra padding e margin

La scatola di un elemento è composta da contenuto, padding, bordo e margine, in quest'ordine dall'interno verso l'esterno. Il suo sfondo normalmente si estende attraverso il padding, mentre il margine è trasparente. Aumentare il padding di un pulsante di solito espande il suo sfondo e l'area cliccabile; aggiungere margine non rende cliccabile quello spazio esterno.

Caratteristica padding margin
Posizione Tra contenuto e bordo All'esterno del bordo
Colore di sfondo normale Viene dipinto anche nel padding Trasparente
Valori negativi Non consentito Consentito
auto Non consentito Consentito; risolto secondo le regole di layout

Entrambe le proprietà accettano valori come px, rem e %, ma padding: auto e padding negativo non sono validi. Per le proprietà di spaziatura fisica di una modalità di scrittura orizzontale ordinaria, i valori percentuali si riferiscono alla larghezza del blocco contenitore, inclusi i valori superiore e inferiore. Non sono percentuali della sua altezza. Definizioni del modello a scatola e della spaziatura W3C

Leggere le direzioni della notazione abbreviata

Un'abbreviazione a quattro valori inizia dall'alto e procede in senso orario: destra, basso, sinistra. Due valori significano verticale e orizzontale; tre significano alto, orizzontale, basso. La stessa regola si applica a padding e margine.

Esempio Alto Destra Basso Sinistra
padding: 10px 10px 10px 10px 10px
padding: 10px 20px 10px 20px 10px 20px
padding: 10px 20px 30px 10px 20px 30px 20px
padding: 10px 20px 30px 40px 10px 20px 30px 40px

Per un lato, usa una proprietà come padding-top o margin-left. Una dichiarazione abbreviata padding o margin scritta in seguito può sovrascrivere i valori dei lati dichiarati in precedenza, quindi controlla l'ordine delle regole.

Verificare le larghezze con un esempio completo

Salva il codice completo qui sotto come spacing.html in UTF-8 e aprilo in un browser. Non servono librerie né un server. Alpha, Beta e le altre parole sono etichette di confronto. Dopo aver modificato, salva e ricarica. Seleziona ciascun .box negli strumenti per sviluppatori e controlla il diagramma del box-model o gli stili calcolati per controllare larghezze e spazi.

<!doctype html>
<html lang="it">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Confronto tra padding e margin</title>
  <style>
    body { font-family: sans-serif; max-width: 640px; margin: 0 auto; padding: 16px; }
    h2 { font-size: 1.1rem; }
    .stage { padding: 12px; border: 1px dashed #777; overflow-x: auto; }
    .box { width: 200px; padding: 16px; border: 4px solid #17324d; margin: 24px; background: #dcefff; }
    .content-box { box-sizing: content-box; }
    .border-box { box-sizing: border-box; }
    .asymmetric { box-sizing: border-box; padding: 8px 16px 24px 32px; margin: 10px 20px 30px 40px; }
    .center { box-sizing: border-box; margin: 0 auto; }
    .collapse-demo { display: flow-root; border: 1px dashed #777; }
    .item { height: 30px; background: #dcefff; }
    .first { margin: 0 0 24px; }
    .second { margin: 16px 0 0; }
  </style>
</head>
<body>
  <h1>Confronto tra padding e margin</h1>
  <h2>content-box</h2>
  <div class="stage"><div class="box content-box">Alpha</div></div>
  <h2>border-box</h2>
  <div class="stage"><div class="box border-box">Beta</div></div>
  <h2>padding / margin</h2>
  <div class="stage"><div class="box asymmetric">Gamma</div></div>
  <h2>margin: 0 auto</h2>
  <div class="stage"><div class="box center">Delta</div></div>
  <h2>margin-bottom / margin-top</h2>
  <div class="collapse-demo">
    <div class="item first">A</div>
    <div class="item second">B</div>
  </div>
</body>
</html>

Alpha ha una larghezza border-box di 200 + 16 × 2 + 4 × 2 = 240px. Inclusi i margini orizzontali, occupa 240 + 24 × 2 = 288px. Beta utilizza il dimensionamento border-box, quindi la sua larghezza border-box è di 200px e la larghezza del contenuto è 200 - 16 × 2 - 4 × 2 = 160px. Questi calcoli escludono il padding e il bordo dell'elemento stage circostante.

Gamma ha un padding di 8px in alto, 16px a destra, 24px in basso e 32px a sinistra. I suoi margini sono 10px, 20px, 30px e 40px nello stesso ordine. Confronta le differenze visibili con le direzioni abbreviate sopra.

Scegliere il calcolo delle dimensioni con box-sizing

Con content-box, width specifica la larghezza del contenuto, con padding e bordo aggiunti all'esterno. Con border-box, la larghezza specificata include contenuto, padding e bordo. Nessuna delle modalità di dimensionamento include il margine nella larghezza. Gli elementi div ordinari utilizzano inizialmente content-box, ma il CSS di reset di un sito potrebbe cambiarlo; controlla il valore calcolato.

Sostituisci la regola .content-box dell'esempio con la seguente. La larghezza border-box di Alpha cambia da 240px a 200px. Mantieni gli altri valori invariati, confronta e ripristina content-box. Se padding e bordo insieme superano la larghezza specificata, la larghezza del contenuto non può diventare negativa, quindi il riquadro risultante può comunque essere più larga del previsto.

.content-box {
  box-sizing: border-box;
}

Spiegazione di box-sizing di MDN

Centrare un blocco con margini automatici

Per centrare orizzontalmente un blocco nel flusso normale, la scatola deve essere più stretta della larghezza disponibile nel suo elemento padre e i suoi margini sinistro e destro devono essere automatici. Delta ha larghezza 200px e margin: 0 auto, quindi lo spazio orizzontale rimanente viene diviso tra entrambi i lati. Solo il centramento non può risolvere l'overflow quando il genitore è troppo stretto.

Se un blocco ordinario con larghezza automatica riempie già lo spazio orizzontale disponibile, aggiungere margini laterali automatici non produce alcun effetto visibile di centramento. Nel flusso normale, margin-top: auto e margin-bottom: auto non lo centrano verticalmente. I margini automatici in Flexbox o Grid seguono regole di layout diverse, quindi distingui quei contesti.

Comprendere il collasso dei margini e i valori negativi

I margini verticali adiacenti idonei possono collassare nel normale layout a blocchi. Nell'ultimo esempio, il margine inferiore di 24px di A e il margine superiore di 16px di B sono entrambi positivi, quindi il loro spazio è il valore maggiore, 24px, invece di 40px. Il bordo del genitore impedisce il collasso dei margini tra quel genitore e i suoi figli in questo esempio.

Modifica la regola .collapse-demo dell'esempio come segue. I suoi figli diventano elementi flex, i cui margini non collassano tra loro, quindi lo spazio diventa 24 + 16 = 40px. Confronta e ripristina display: flow-root. Applicare flow-root solo a un genitore non elimina tutto il collasso dei margini tra blocchi fratelli.

.collapse-demo {
  display: flex;
  flex-direction: column;
  border: 1px dashed #777;
}

Nella modalità di scrittura orizzontale utilizzata qui, i margini sinistro e destro non collassano in questo modo. Quando i margini che collassano includono valori positivi e negativi, aggiungi il valore positivo più grande al valore negativo con la maggiore valore assoluto: 24px e -8px producono 16px. Se tutti sono negativi, usa il valore più negativo; -8px e -16px producono -16px. Una dichiarazione come margin-left: -8px è valida ma può causare sovrapposizioni o spostare il contenuto fuori dal suo genitore. Controlla schermi stretti e indicatori del focus da tastiera. Il padding negativo non può produrre lo stesso effetto. Regole W3C sulla fusione dei margini

Verificare una spaziatura inattesa

  1. Controlla i valori predefiniti del browser. Il margine predefinito dell’elemento body o i margini verticali predefiniti di p e h1 possono far sembrare la spaziatura più grande delle tue dichiarazioni. Resetta gli elementi rilevanti invece di rimuovere alla cieca tutta la spaziatura.
  2. Per un elemento in linea ordinario non sostituito come span, i margini verticali non influenzano la disposizione delle linee. Il padding degli elementi inline può essere dipinto senza separare le linee adiacenti come previsto. Considera inline-block o un'altra modalità di layout quando la scatola necessita di dimensionamento e spaziatura indipendenti.
  3. Usa strumenti di sviluppo per verificare che il selettore corrisponda, che la dichiarazione sia valida e che una regola di priorità superiore o una dichiarazione abbreviata successiva non l'abbiano sovrascritta. Confronta anche a una larghezza ristretta, controllando l'overflow e l'effetto del padding sulla larghezza.

Per definire la spaziatura rispetto alla direzione di scrittura, usa proprietà logiche come padding-inline e margin-block. Nella scrittura orizzontale ordinaria, l'asse in linea è orizzontale e l'asse del blocco è verticale. Questi assi cambiano nella scrittura verticale, quindi non corrispondono sempre ai lati fisici sinistro e destro.