Indice
Il responsive design è stato per anni sinonimo di Media Queries: breakpoint, viewport e adattamento alle dimensioni dello schermo. Ma il web si è evoluto, e con esso le nostre esigenze di progettazione. Oggi, grazie alle Container Queries, possiamo creare layout davvero modulari, in grado di adattarsi non solo al dispositivo, ma anche al contesto in cui ogni componente viene inserito. Un passo avanti enorme verso un design più flessibile, scalabile e indipendente dalla struttura globale della pagina.
Media Queries
Media queries vs container queries
A differenza delle container queries, le media queries controllano il layout e gli stili in base alle dimensioni del viewport (ovvero in base alla larghezza della finestra del browser).
Quanto è grande la finestra del browser?
@media (min-width: 480px) {
main { width: 89%; }
}
I browser comprendono le query relative alle dimensioni, all'orientamento e alla risoluzione del monitor o della finestra del browser.
/* Piccoli schermi: layout verticale */
.responsive-grid {
display: grid;
font-family: Arial, sans-serif;
grid-gap: 10px;
}
/* Schermi medi: 2 colonne */
@media (min-width: 700px) {
.responsive-grid {
grid-template-areas:
"box1 box2"
"box3 box4"
"box5 box6";
}
}
/* Schermi grandi: 3 colonne */
@media (min-width: 1200px) {
.responsive-grid {
grid-template-areas:
"box1 box1 box1"
"box2 box3 box4"
"box5 box5 box4"
"box6 box6 box4";
}
}
Come vengono utilizzate le media query?
Le media query non richiedono solo la risoluzione, le dimensioni e l'orientamento del viewport, ma anche, ad esempio, la modalità diurna o notturna del visitatore:
@media (prefers-color-scheme: dark) {
body {
background-color: #2a3b2a;
color: #e0e0e0;
}
}
@media print {
body {
font-size: 13pt;
font-family: Georgia, serif;
}
}
@media (hover: hover) {
button {
background-color: lightsteelblue;
color: darkslategray;
transition: background-color 0.3s;
}
button:hover {
background-color: steelblue;
}
}
Regola multimediale e breakpoint
Le media query sovrascrivono solo le proprietà che cambiano o vengono aggiunte in un breakpoint.
Un design reattivo non solo si adatta ai monitor degli smartphone, ma offre anche un design coordinato per diverse finestre del browser (viewport): valore aggiunto per monitor di grandi dimensioni e un design compatto per finestre del browser di piccole dimensioni.
Struttura delle media query
Oggi esistono molte classi di dispositivi: smartphone, tablet, laptop e monitor di grandi dimensioni. Per ognuna di queste “classi” possiamo definire un foglio di stile dedicato o regole CSS specifiche.
Nel tag <link> del file HTML possiamo indicare una condizione tramite l’attributo media, che dice quando quel foglio di stile deve essere caricato.
<link rel="stylesheet" href="base.css" media="all"> <link rel="stylesheet" href="tablet.css" media="(min-width: 700px)"> <link rel="stylesheet" href="desktop.css" media="(min-width: 1100px)"> <link rel="stylesheet" href="print.css" media="print">
@media only screen and (min-width: 44em) and (max-width: 68em) {
/* circa 704px – 1088px → tipico range per tablet */
main {
max-width: 90%;
margin: 0 auto;
font-size: 1.1rem;
}
.sidebar {
display: none;
}
}
Il Viewport dei dispositivi mobile
Facciamo un esempio: l'Iphone 11 ha una risoluzione fisica dello schermo di 828 x 1792 pixel, ma comunica al browser che la finestra (il viewport) misura solo 414 x 896 pixel.
Questo succede perché gli schermi moderni (come i “Retina Display”) hanno una densità di pixel molto più alta rispetto ai monitor normali. Ogni “pixel CSS” corrisponde in realtà a più pixel fisici (spesso 2 o 3).
Il browser quindi ridimensiona (zooma) la pagina automaticamente: riduce la scala dei contenuti in modo che tutta la larghezza della pagina entri nello schermo, così l’utente può vedere il sito intero fin da subito, senza scorrere orizzontalmente.
Facciamo un altro esempio: Google Pixel 8 ha uno schermo da 6,2 pollici con una dimensione dello schermo (risoluzione): 1080px × 2400px. Il browser però dice di avere solo 412px × 915px come viewport “logico”. Questo succede perché ogni pixel CSS corrisponde a circa 2,6 pixel fisici.
Quando viene aperta una pagina web, il telefono la ridimensiona automaticamente (zoom out), la adatta alla larghezza dello schermo e poi permette di ingrandire (zoom in) se l’utente vuole leggere meglio.
Nel file HTML, si usa spesso il meta tag viewport per controllare questo comportamento:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
initial-scale=1.0 mostra la pagina senza zoom iniziale, alla scala naturale.
Se questo tag non è presente, il browser mobile “finge” che la pagina sia larga 980px (o più) e la riduce per farla entrare nello schermo, risultando spesso troppo piccola.
Container Queries
Con le container queries, un elemento si adatta alla larghezza del suo contenitore principale e non alla larghezza del viewport, come nel caso delle query multimediali. Ciò è perfetto per componenti modulari e riutilizzabili.
Un esempio sono gli estratti dei post del blog che vengono inseriti in una barra laterale o in un layout a griglia. Anche la disposizione dei post del blog nella griglia della pagina iniziale rispetto alla barra laterale rientra in questa categoria. Di solito, il layout mostra le schede e i loro contenuti in righe una sotto l'altra nei viewport stretti, e solo nei viewport più larghi vengono affiancate due o più schede. Quando compaiono due o più schede affiancate, le immagini diventano sovradimensionate: in questo caso è più efficiente affiancare anche i contenuti delle schede.
A differenza delle media queries, le container queries reagiscono alle dimensioni del contenitore superiore, non all'intero viewport.
Concetti chiave per le container queries
.article-container {
container-type: inline-size;
padding: 16px;
width: 100%;
max-width: 940px;
background-color: #e0e0e0;
border-radius: 8px;
}
2. Inoltre, è possibile impostare container-name per accedere in modo mirato al container.
.content-box {
container-type: inline-size;
container-name: article;
}
@container (min-width: 420px) {
.article {
display: grid;
grid-template-columns: 2fr 3fr;
grid-template-areas:
"title title"
"media text";
gap: 1.2rem;
align-items: start;
}
}
@container article (min-width: 420px) {
/* Regole applicate agli elementi all’interno del container “article” */
}
Card
Se questi elementi di layout non si trovano solo nell'area principale della pagina, ma compaiono anche nelle barre laterali o nei piè di pagina, vengono utilizzate anche le query contenitore.
/* Contenitori principali (sezione e aside) */
.main-section,
.side-panel {
min-width: 150px;
container-type: inline-size;
container-name: gallery;
}
/* Da 480px in su → 2 schede per riga */
@container gallery (min-width: 480px) {
.card-list {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.card-item {
flex: 1 1 calc(50% - 1rem);
}
}
/* Da 900px in su → 3 schede per riga */
@container gallery (min-width: 900px) {
.card-item {
flex: 1 1 calc(33.333% - 1rem);
}
}
È possibile utilizzare le query contenitore nei tag <img> per le dimensioni?
Una di queste è proprio dentro il tag <img>, negli attributi srcset e sizes.
Quando il browser legge l’HTML, sceglie subito quale immagine caricare (in base a srcset e sizes). Questo avviene prima che il CSS venga applicato, quindi le Container Queries non sono ancora “attive”.
Perciò, scrivere qualcosa come:
sizes="container(max-width: 600px) 420px, 920px"
Se un’immagine può stare in contenitori di dimensioni diverse (ad esempio 920px o 1440px), non si può chiedere al browser di adattarsi in base al container. Bisogna piuttosto:
- usare più tag <img> per situazioni diverse (ad esempio un’immagine più larga e una più stretta),
- oppure gestire tutto con @media queries nel CSS, che guardano la larghezza del viewport (non del container).