POST
CSS: facciamo amicizia con il padding
Mi è capitato spesso di voler creare un contenitore che fosse largo il 100% di suo “padre”, ma non volere che il suo contenuto restasse incollato ai bordi sinistro e destro.
La prima idea che mi veniva in mente era creare un tag div
dentro il contenitore e assegnargli un padding
.
Vediamo cosa succede. Partiamo da un div
contenitore vuoto…
Container
…e inseriamo un div
con questo stile:
.someclass {
width: 100%;
padding: 10px;
}
I risultati sono questi. 😒
Perché il secondo div
trabocca?
Di default, il browser calcola la larghezza degli elementi sommando:
- la larghezza esplicita dell’elemento (l’ attributo width)
- padding sul lato destro e sinistro
- bordo sul lato destro e sinistro
quindi, per il nostro div
la larghezza calcolata sarà:
- 100% (dell’elemento padre) +
- 20 pixel di padding (10 a destra e 10 a sinistra) +
- 0 pixel di bordo.
Totale: 20 pixel più del contenitore.
La situazione ovviamente peggiora aggiungendo un bordo:
Ora la larghezza del div
interno è (2 volte il padding + 2 volte il bordo) in più della larghezza del contenitore.
Il problema è che vogliamo ottenere una larghezza pari al 100%, espressa in unità percentuali, ma per farlo dovremmo sottrarre alla larghezza il padding
, che vogliamo esprimere in pixel (px
) o em
, o rem
, cioè in un’unità diversa.
Non è possibile sottrarre l’uno all’altra ad es. usando un’espressione:
.someclass {
width: 100%-20px;
padding: 10px;
}
La riga evidenziata produrrà un errore e non verrà interpretata come vorremmo. 😄
Si potrebbe aggirare l’ostacolo con due div
uno dentro l’altro, il più esterno largo il 100% e il più interno con un margine, come segue:
.someclass_outer {
width: 100%;
}
.someclass_inner {
margin: 10px;
}
Nostrum minima quia est et veniam. Voluptas qui impedit cum voluptas esse. Magnam necessitatibus autem laudantium voluptatibus tempora. Quam praesentium quia a explicabo ut beatae dolores.
Questo metodo ha due controindicazioni:
- complica il markup (HTML) e il foglio di stile (CSS);
- se volessimo aggiungere un bordo a
someclass_outer
, lo spessore del bordo verrebbe aggiunto alla larghezza deldiv
esterno, facendoci ricadere nel problema precedente.
Le due soluzioni possibili
Soluzione 1: usare calc()
In effetti quando abbiamo scritto:
.someclass {
width: 100%-20px;
padding: 10px;
}
ci eravamo quasi… ci mancava solo “avvolgere” il valore di width
dentro la funzione CSS calc()
:
.someclass {
width: calc(100%-20px-1rem);
padding: 10px;
border: .5rem dashed #ffb700;
}
La funzione calc()
fa proprio quello che ci aspetteremmo: calcola un valore valutando un’espressione.
In questo modo, la larghezza del div
interno sarà calcolata come 100% del suo contenitore, meno 20 pixel e 1 rem.
Tenetur nihil repellat doloribus qui possimus. Neque dolorum dignissimos excepturi. Odit laboriosam excepturi quod. Consectetur aliquam inventore quae deleniti consequatur ipsam in sed. Dolore dignissimos placeat iusto ratione.
Ci siamo, ma se cambiamo i valori di padding e/o spessore del bordo, dovremo aggiustare la formula di conseguenza.
Soluzione 2: usare box-sizing
Per evitare di legare la larghezza ai valori di padding e bordo, possiamo sfruttare la proprietà CSS box-sizing
. Essa, oltre ad essere una soluzione è taoisticamente
, anche la causa del problema 😄.
box-sizing
ammette i seguenti valori:
content-box
(default): gli attributi width ed height indicano larghezza e altezza del box esclusi padding e bordo.border-box
: gli attributi width ed height indicano larghezza e altezza del box inclusi padding e bordo. Questo è il valore che ci serve.initial
: reimposta al valore di default (quindi, equivalente acontent-box
).inherit
: eredita il valore dall’elemento padre.
Se usiamo box-sizing: border-box;
nello stile inline del nostro elemento, o in una classe CSS, il browser farà in modo che il valore dell’attributo width
sia la larghezza totale dell’elemento inclusi padding e bordo, qualunque valore assumano.
Ad esempio:
.someclass {
box-sizing: border-box;
width: 100%;
padding: 10px;
border: .5rem dashed #ffb700;
}
In questo modo, il div
interno, inclusi i 20 pixel di padding e gli (0.5rem x 2) di bordo, sarà largo il 100% del suo contenitore. Personalmente preferisco questa soluzione perché la trovo più elegante.
Tenetur nihil repellat doloribus qui possimus. Neque dolorum dignissimos excepturi. Odit laboriosam excepturi quod. Consectetur aliquam inventore quae deleniti consequatur ipsam in sed. Dolore dignissimos placeat iusto ratione.
Missione compiuta! 🚀
🔗 Riferimenti esterni
- Funzione
calc()
su Mozilla Developer Network - Proprietà
box-sizing
su Mozilla Developer Network - Funzione
calc()
su W3Schools - Proprietà
box-sizing
su W3Schools
📷 **Immagine di copertina**
By Bagok (Own work) CC BY-SA 3.0, via Wikimedia Commons