A volte il primo pezzo di HTML che scriviamo in un nuovo documento è un elemento che avvolge tutto il resto della pagina. Il termine wrapper è comune per questo. Gli diamo una classe, e quella classe è responsabile dell’incapsulamento di tutti gli elementi visivi sulla pagina.
Ho sempre lottato per il modo migliore di implementarlo. Ho trovato un thread correlato su StackOverflow che ha più di 250.000 visualizzazioni, quindi ovviamente non sono l’unico a chiederselo! Riassumerò i miei ultimi pensieri in questo articolo.
Prima di tuffarci, esaminiamo prima la differenza tra il “wrapper” e il “container”.
“Wrapper” vs “Container”
Credo ci sia una differenza tra elementi wrapper e container.
Nei linguaggi di programmazione, la parola container è generalmente usata per strutture che possono contenere più di un elemento. Un wrapper, invece, è qualcosa che avvolge un singolo oggetto per fornirgli più funzionalità e interfaccia.
Quindi, secondo me, ha senso avere due nomi diversi perché intendono funzioni diverse.
Parlando del wrapper, è comune pensare a un <div>
che contiene tutto il resto dell’HTML del documento. Sono sicuro che molti di noi hanno vissuto un periodo in cui lo abbiamo impostato a 960px di larghezza e allineato al centro tutto il nostro contenuto principale. I wrapper sono anche usati per cose come l’applicazione di un piè di pagina appiccicoso.
Il contenitore, d’altra parte, di solito intende un altro tipo di contenimento. Uno che a volte è necessario per implementare un comportamento o uno stile di più componenti. Serve allo scopo di raggruppare gli elementi sia semanticamente che visivamente. Per esempio, Bootstrap ha delle “classi contenitore” che ospitano il loro sistema a griglia o contengono vari altri componenti.
I termini wrapper e container possono anche significare la stessa cosa a seconda dello sviluppatore e di ciò che intendono. Ci potrebbero essere anche altre convenzioni, quindi il miglior consiglio è di solito quello di implementare quello che ha più senso per voi. Ma ricordate, la denominazione è una delle parti più fondamentali e importanti delle attività dello sviluppatore. Le convenzioni di denominazione rendono il nostro codice più leggibile e prevedibile. Scegliete con attenzione!
Ecco un esempio di un generico wrapper di pagina:
/** * 1. Centers the content. Yes, it's a bit opinionated. * 2. See the "width vs max-width" section * 3. See the "Additional Padding" section */.wrapper { margin-right: auto; /* 1 */ margin-left: auto; /* 1 */ max-width: 960px; /* 2 */ padding-right: 10px; /* 3 */ padding-left: 10px; /* 3 */}
width vs max-width
Impostare il width
di un elemento a livello blocco gli impedirà di estendersi fino ai bordi del suo contenitore (buono per cose come la lunghezza delle linee leggibili). Pertanto, l’elemento wrapper occuperà la larghezza specificata. Il problema si verifica quando la finestra del browser è più stretta della larghezza specifica del wrapper. Questo innescherà una barra di scorrimento orizzontale, che è quasi sempre indesiderabile.
Utilizzare max-width
invece, in questa situazione, è meglio per finestre del browser più strette. Questo è importante quando si rende un sito utilizzabile su piccoli dispositivi. Ecco un buon esempio che mostra il problema.
Vedi la penna CSS-Tricks: The Best Way to Implement a CSS Wrapper by Kaloyan Kosev (@superKalo) on CodePen.
In termini di reattività, max-width
è la scelta migliore!
Additional Padding
Ho visto molti sviluppatori dimenticare un particolare caso limite. Diciamo che abbiamo un wrapper con max-width
impostato a 980px. L’edge case appare quando la larghezza dello schermo del dispositivo dell’utente è esattamente 980px. Il contenuto quindi si incollerà esattamente ai bordi dello schermo senza lasciare alcuno spazio di respiro.
Di solito vogliamo un po’ di padding sui bordi. Ecco perché se devo implementare un wrapper con una larghezza totale di 980px, lo farei così:
.wrapper { max-width: 960px; /* 20px smaller, to fit the paddings on the sides */ padding-right: 10px; padding-left: 10px; /* ... */}
Pertanto, ecco perché aggiungere padding-left
e padding-right
al vostro wrapper potrebbe essere una buona idea, specialmente su mobile.
Oppure, considerate di usare il box-sizing in modo che il padding non cambi affatto la larghezza complessiva.
Quale elemento HTML scegliere
Un wrapper non ha alcun significato semantico. Semplicemente contiene tutti gli elementi visivi e il contenuto della pagina. È solo un contenitore generico. In termini di semantica, <div>
è la scelta migliore. Anche il <div>
non ha alcun significato semantico ed è solo un contenitore generico.
Ci si potrebbe chiedere se forse un elemento <section>
potrebbe adattarsi a questo scopo. Tuttavia, ecco cosa dice la specifica W3C:
L’elemento
<section>
non è un elemento contenitore generico. Quando un elemento è necessario solo per scopi di stile o come comodità per lo scripting, gli autori sono incoraggiati ad usare invece l’elemento div. Una regola generale è che l’elemento sezione è appropriato solo se il contenuto dell’elemento sarebbe elencato esplicitamente nel sommario del documento.
L’elemento <section>
ha una semantica propria. Rappresenta un raggruppamento tematico di contenuto. Il tema di ogni sezione dovrebbe essere identificato, tipicamente includendo un titolo (elemento h1-h6) come figlio dell’elemento section.
Esempi di sezioni sarebbero i capitoli, le varie pagine a schede in una finestra di dialogo a schede, o le sezioni numerate di una tesi. La home page di un sito web potrebbe essere divisa in sezioni per un’introduzione, notizie e informazioni di contatto.
Potrebbe non sembrare molto ovvio a prima vista, ma sì! Il semplice vecchio <div>
si adatta meglio ad un wrapper!
Usando il tag <body> vs. Utilizzando un ulteriore <div>
Va detto che ci saranno alcuni casi in cui si potrebbe utilizzare l’elemento <body>
come wrapper. La seguente implementazione funzionerà perfettamente:
body { margin-right: auto; margin-left: auto; max-width: 960px; padding-right: 10px; padding-left: 10px;}
E risulterà in un elemento in meno nel vostro markup perché potete eliminare quel wrapper non necessario <div>
in questo modo.
Tuttavia, non lo raccomanderei, a causa della flessibilità e resilienza ai cambiamenti. Immaginate se in una fase successiva del progetto si verificasse uno di questi scenari:
- Avete bisogno di imporre un piè di pagina da “attaccare” alla fine del documento (in fondo al viewport quando il documento è corto). Anche se puoi usare il modo più moderno per farlo – con flexbox, hai bisogno di un ulteriore wrapper
<div>
. - Hai bisogno di impostare il
background-color
dell’intera pagina. Normalmente, qualunque sia lo sfondo impostato sul<body>
si comporterà come se fosse stato impostato sull’elemento<html>
se questo non ha già uno sfondo. Solo una cosa strana nei CSS. Ma se il vostro elemento<html>
ha già uno sfondo, e impostate il corpo su qualcos’altro, e il corpo ha qualsiasi tipo di vincolo di spaziatura, gli sfondi diventeranno strani. È una cosa complicata.
Concluderei che è ancora una buona pratica avere un ulteriore <div>
per implementare un wrapper CSS. In questo modo, se i requisiti delle specifiche cambiano in seguito, non è necessario aggiungere il wrapper più tardi e occuparsi di spostare gli stili. Dopo tutto, stiamo parlando solo di un elemento DOM in più.