Media query CSS
Il linguaggio CSS (“Cascading Style Sheets”, in italiano “fogli di stile a cascata”), insieme a HTML e JavaScript, rappresenta la struttura di base per lo sviluppo di siti web moderni. Il CSS è un linguaggio di programmazione, ma non descrive i singoli passaggi necessari per risolvere un problema. Si definisce invece un obiettivo da raggiungere. Il CSS è quindi un linguaggio dichiarativo simile a SQL. Parte dei CSS sono le cosiddette media query, che interrogano le proprietà di un dispositivo di output. Sono utilizzate per il responsive web design. Come funziona esattamente?
- Certificato SSL Wildcard incluso
- Registrazione di dominio sicura
- Indirizzo e-mail professionale da 2 GB
Cosa sono le media query CSS?
Le media query CSS sono state introdotte con la specifica CSS3. Una media query lega l’assegnazione delle proprietà CSS di un elemento a una o più condizioni del supporto. Nel caso più semplice, viene fatta una distinzione tra il supporto su cui l’informazione viene visualizzata, ad esempio su uno schermo, una pagina stampata (che include l’output in formato PDF) oppure come testo letto ad alta voce:
Supporto | Spiegazione |
---|---|
all (tutti) | Qualsiasi supporto di output |
screen (schermo) | Visualizzazione del contenuto di una pagina web su uno schermo a scorrimento |
print (stampa) | Visualizzazione del contenuto di una pagina web su più pagine con dimensioni fisse |
speech (testo parlato) | Lettura ad alta voce del contenuto di una pagina web tramite un sintetizzatore vocale |
Una media query CSS viene specificata all’interno di un blocco di codice CSS usando una regola speciale '@media'. I selettori CSS e le regole in essi contenuti sono attivati solo nella condizione specificata. Ad esempio, gli elementi che non possono essere visualizzati possono essere nascosti quando vengono emessi come pagina stampata:
/* Nascondere gli elementi non stampabili */
@media print {
video, audio {
display: none;
}
}
Oltre il supporto da utilizzare, le media query CSS possono essere utilizzate per interrogare proprietà specifiche del rispettivo supporto. Queste query CSS sono quindi la caratteristica tecnica centrale che ha reso davvero possibile il responsive web design.
Media query CSS come elemento di controllo centrale per il responsive web design
Il responsive web design mira ad adattare la visualizzazione di una pagina web al rispettivo dispositivo nel miglior modo possibile. Le media query sono usate per interrogare varie proprietà del dispositivo di visualizzazione, le cosiddette media feature. Tra le altre cose, è possibile definire regole di stile per diverse dimensioni dello schermo. Inoltre, regole di stile ottimizzate possono essere definite nel caso in cui un dispositivo mobile sia inclinato.
Illustriamo di seguito una panoramica delle media feature attualmente più usate per il responsive design:
Media feature | Spiegazione |
---|---|
width (larghezza) | Interroga la larghezza dello schermo in pixel |
height (altezza) | Interroga l’altezza dello schermo in pixel |
orientation (orientamento) | Rileva l’orientamento dello schermo in formato verticale/orizzontale |
resolution (risoluzione) | Rileva la risoluzione dello schermo disponibile |
Vediamo alcuni esempi. Immaginiamo il titolo principale di una pagina web. L’HTML fornisce l’elemento ‘h1’. Per prima cosa, per l’elemento h1 imposteremo le regole di stile indipendentemente dal dispositivo di visualizzazione:
h1 {
font-size: 24px;
line-height: 1.25;
}
A questo punto, definiamo una media query che interroga la larghezza dello schermo. All’interno della query, specifichiamo le regole di stile che dovrebbero essere applicate al titolo a partire da questa larghezza. Nell’esempio specifico, aumentiamo la dimensione del carattere del titolo h1 sugli schermi che sono larghi almeno 1.024 pixel:
@media screen and (min-width: 1024px) {
h1 {
font-size: 36px;
}
}
Notate che nell’esempio stiamo solo regolando la proprietà ‘font-size’ dell’intestazione h1. L’interlinea è definita dalla proprietà ‘line-height’ come unità relativa e viene ereditata poiché non è esplicitamente sovrascritta. Nell’esempio concreto, l’interlinea dell’elemento h1 nello stato base è 24px * 1,25 = 30px. Su schermi larghi almeno 1.024 pixel, l’interlinea proporzionale è pari a 36px * 1,25 = 45px.
Questa amalgama di regole di stile esistenti e appena definite è suggerita dal termine “cascading” (a cascata) della denominazione CSS, che sta a indicare che un elemento eredita regole di stile da elementi genitori o regole generali che sono già state definite. Di solito, si impostano le proprietà di base degli elementi e poi si sovrascrivono selettivamente le proprietà in determinate condizioni.
Un altro esempio: immaginiamo di voler mostrare tre elementi in un contenitore. Gli elementi sullo schermo di un dispositivo mobile devono essere visualizzati uno sotto l’altro quando il dispositivo è tenuto in posizione verticale. Quando si inclina il dispositivo orizzontalmente, il layout dovrebbe cambiare in modo che gli elementi siano visualizzati fianco a fianco. Con il modulo flexbox layout e una media query CSS, che interroga l’orientamento del dispositivo, il layout può essere implementato in poche righe di HTML e CSS. Prima definiamo il contenitore e gli elementi contenuti nell’HTML:
<div class="container">
<div class="element">…</div>
<div class="element">…</div>
<div class="element">…</div>
</div>
Definiamo inoltre le seguenti regole CSS. Impostiamo la proprietà ‘display: flex’ sul contenitore e, per questo elemento, impostiamo condizionatamente la proprietà ‘flex-direction’ tramite media query CSS. Quando il dispositivo è in modalità di visualizzazione orizzontale, gli elementi sono visualizzati in fila, uno accanto all’altro; quando è in modalità verticale, gli elementi sono disposti in colonna, uno sotto l’altro:
.container {
display: flex;
}
/* Formato orizzontale */
@media screen and (orientation: landscape) {
.container {
flex-direction: row;
}
}
/* Formato verticale */
@media screen and (orientation: portrait) {
.container {
flex-direction: column;
}
}
Oltre alle dimensioni dello schermo e all’orientamento del dispositivo, possiamo anche interrogare la risoluzione fisica dello schermo tramite media query. Ciò è particolarmente interessante per visualizzare immagini in pixel. Ad esempio, immaginate che un logo sia disponibile in due versioni, ognuna ottimizzata per schermi a bassa e alta risoluzione. Un semplice trucco per visualizzare il logo appropriato in ogni caso è quello di mettere entrambe le varianti nella pagina. Con la media query CSS interroghiamo la risoluzione dello schermo e nascondiamo la versione non necessaria tramite ‘display: none’. Questo approccio potrebbe apparire così implementato nel codice HTML e CSS:
<!-- Immagine ad alta risoluzione -->
<img class="logo--high-res" src="/img/logo-high-res.png" alt="Logo ad alta risoluzione">
<!-- Immagine a bassa risoluzione -->
<img class="logo--low-res" src="/img/logo-low-res.png" alt="Logo a bassa risoluzione">
/* Nascondere su schermi a bassa risoluzione le immagini ad alta risoluzione */
@media (max-resolution: 149dpi) {
.logo--high-res {
display: none;
}
}
/* Nascondere su schermi ad alta risoluzione le immagini a bassa risoluzione */
@media (min-resolution: 150dpi) {
.logo--low-res {
display: none;
}
}
Nel nostro articolo sul responsive web design vi mostriamo altre opzioni per visualizzare le immagini in modo ottimale e reattivo.
Attivare le variabili viewport per il responsive design
Nelle spiegazioni precedenti abbiamo parlato di “schermo” in riferimento alla larghezza disponibile sul supporto di output. Ciò è vero dal punto di vista concettuale, ma a livello tecnico non è del tutto corretto. Il browser opera internamente basandosi sul concetto di “viewport”. Affinché la larghezza di viewport corrisponda effettivamente alla larghezza dello schermo, è necessario inserire l’indicazione ‘meta-viewport’ nella sezione ‘<head>‘ dei file HTML. In assenza di questa indicazione, il sito viene visualizzato sui dispositivi mobili come se fosse su desktop, ma nel complesso con dimensioni estremamente ridotte.
<head>
<!-- Attivare le media query CSS -->
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
Capire le unità CSS per il responsive web design
Nel responsive web design gli elementi devono adattarsi alla superficie dello schermo. Spesso si tratta di definire le dimensioni degli elementi in varie condizioni. La specifica CSS ingloba una grande varietà di unità e, tra queste, l’unità di misura più semplice è sicuramente il pixel. Ad esempio, un’immagine da 1080p presenta dimensioni pari a 1.920 pixel di larghezza per 1.080 pixel di altezza.
Il pixel è un’unità assoluta e, per definizione, non si adatta allo spazio esistente. Vediamo un esempio per cui questa situazione potrebbe rivelarsi un problema. Supponiamo che un sito web contenga un’immagine con una larghezza di 1.920 pixel. Se definiamo questo valore per la larghezza dell’immagine tramite CSS, potrebbero verificarsi anomalie nella visualizzazione su schermi piccoli, in cui l’immagine occupa uno spazio superiore a quello disponibile.
In questo esempio definiamo un’immagine in HTML con il tag ‘<img>‘:
<img class="img-1080p" src="/immagine-1080p.png">
Tramite CSS blocchiamo la larghezza a 1.920 pixel:
.img-1080p {
width: 1920px;
}
In questo scenario sarebbe stato meglio utilizzare un’unità relativa al posto dei pixel. Fin dai primi tempi dei layout basati su tabella il CSS riconosce la percentuale come unità relativa. Se impostiamo la larghezza dell’immagine tramite CSS su ‘100%’, l’immagine si adatta in modo fluido allo spazio esistente. Ciò funziona perché i valori percentuali si riferiscono sempre all’elemento circoscritto.
img {
width: 100%;
}
Abbiamo fatto un altro passo avanti verso il nostro obiettivo, ovvero quello di adattare la larghezza di un’immagine allo spazio disponibile. Tuttavia, abbiamo creato un nuovo problema: infatti, su uno schermo con una larghezza superiore a 1.920 pixel, l’immagine viene visualizzata ingrandita e quindi risulta pixelata. Per questo dobbiamo anche limitare la larghezza massima dell’immagine alle relative dimensioni effettive in pixel:
.img-1080p {
/* ereditato implicitamente da `img` */
/* width: 100%; */
max-width: 1920px;
}
Oltre ai pixel e alla percentuale, il CSS conosce una serie di altre unità. Le unità relative em, rem e vw, vh offrono tutte interessanti possibilità di utilizzo nel responsive design. Di seguito trovate una panoramica delle unità CSS più usate per il responsive design con il relativo utilizzo:
Unità CSS | Utilizzo |
---|---|
rem | Dimensione del carattere nel corpo del testo, 'max-width' degli elementi di layout; 'width' degli elementi |
% | 'width' delle immagini e degli elementi di layout, eventualmente limitata da 'max-width' |
vw, vh | Dimensione del carattere dei titoli, dei testi dei banner, dimensioni degli elementi a schermo intero |
em | Definizione dei breakpoint, 'max-width' degli elementi di layout |
px | Definizione dei breakpoint, 'max-width' delle immagini |
Capire le media query avanzate
In aggiunta alle semplici media query finora presentate è possibile scrivere anche media query CSS complesse. A tale riguardo il CSS prevede l’uso degli operatori logici ‘and’, ‘or’ e ‘not’. Di seguito trovate un esempio di query complessa:
@media screen and (min-width: 30em) and (orientation: landscape) { /* … */ }
Oltre alle media feature già definite, che si possono interrogare tramite media query CSS, in futuro sarà disponibile una serie di altre interessanti funzionalità. La specifica “CSS Media Queries Level 5” (CSS5) fornisce, tra le altre cose, le seguenti nuove opzioni di query:
Media feature | Spiegazione |
---|---|
light-level | Rileva la luminosità dell’ambiente |
prefers-color-scheme | Seleziona uno schema di colori chiaro o scuro |
prefers-contrast | Seleziona la modalità ad alto contrasto |
Un’altra novità prevista con l’arrivo del CSS5 sono le cosiddette container query. Grazie a queste query sarà possibile per la prima volta collegare le regole di stile per gli elementi alle proprietà del contenitore. Le container query sono quindi in contrapposizione con le media query CSS, che interrogano le proprietà globali del dispositivo di visualizzazione. L’uso delle container query consente di gestire casi speciali, per i quali in passato si ricorreva a JavaScript o a media query complesse.
Capire i breakpoint CSS
In relazione al responsive web design e alle media query CSS si parla spesso di “breakpoint” (in italiano: “punti di interruzione”). Un breakpoint è la larghezza definita dello schermo, per cui viene attivato un set di regole CSS, definito tramite media query CSS. Si possono visualizzare i breakpoint definiti su un sito web aprendo gli strumenti di sviluppo nel browser. Se è attiva la visualizzazione responsive, i breakpoint vengono visualizzati come barre colorate sopra la pagina web.
Capire il Mobile first, i processori CSS e i framework di utilità CSS
Una pratica consigliata riconosciuta per il responsive web design è l’approccio Mobile first. Se il design e lo sviluppo di un sito web seguono questo approccio, vengono prima di tutto definite le informazioni di stile per gli schermi più piccoli. Queste definizioni costituiscono la struttura di base del design. Basandosi su di essa verranno definiti diversi breakpoint per schermi progressivamente più grandi. All’interno dei breakpoint vengono definite in modo selettivo nuove regole di stile per gli elementi e quindi vengono sovrascritte le regole esistenti per gli schermi più piccoli.
/* Breakpoint Tachyons */
/* 'not-small' Breakpoint */
@media screen and (min-width: 30em) { /* … */ }
/* 'medium' Breakpoint */
@media screen and (min-width: 30em) and (max-width: 60em) { /* … */ }
/* 'large' Breakpoint */
@media screen and (min-width: 60em) { /* … */ }
Si noti che seguendo l’approccio Mobile first non esiste un vero breakpoint ‘small’. Le informazioni per i piccoli dispositivi vengono definite semplicemente senza breakpoint.
Breakpoint Tachyons | Spiegazione |
---|---|
not-small | Comprende le larghezze dello schermo dei breakpoint ‘medium’ e ‘large’ |
medium | Comprende le larghezze dello schermo tra i breakpoint ‘not-small’ e ‘large’ |
large | Comprende solo schermi di grandi dimensioni |
All’interno dei breakpoint vengono definite le regole di stile per gli elementi, la cui visualizzazione deve essere adattata a schermi di varie dimensioni. Probabilmente avete già capito che questa centralizzazione della base di codice CSS di un progetto web costituisce un problema. Di solito è preferibile raccogliere tutte le proprietà CSS di un elemento in un file separato.
- Impostazioni SEO integrate
- Strumento per prenotazioni online
- Dominio e certificato SSL inclusi
Capire i preprocessori e i postprocessori CSS
Per modulare il codice CSS di un progetto, all’inizio venivano utilizzati diversi preprocessori CSS. Forse i nomi dei linguaggi Sass, Less o Stylus vi suonano familiari. In seguito, con il progetto Node.js si è aggiunto il PostCSS, un postprocessore CSS. Tutte le tecnologie menzionate consentono di incapsulare le media query CSS sotto un selettore CSS. In questo modo le regole di stile di un elemento possono essere definite collettivamente per tutte le condizioni dei supporti. Di seguito è riportato un esempio con Stylus.
File Stylus ‘text.styl’ per proprietà del testo:
// Definizioni Mobile First
p
font-size: 16px
// Definizioni per breakpoint 'not-small'
@media screen and (min-width: 30em)
font-size: 18px
File Stylus 'link.styl' per proprietà di link:
// Definizioni Mobile First
a
color: blue
// Definizioni per breakpoint 'not-small'
@media screen and (min-width: 30em)
text-decoration: underline
Il processore Stylus traduce i file in CSS e raccoglie le regole media query CSS inserite sotto un unico breakpoint. Il codice Stylus visualizzato viene tradotto nel seguente codice CSS:
/* Definizioni Mobile First */
p {
font-size: 16px;
}
a {
color: blue;
}
/* Definizioni per breakpoint 'not-small' */
@media screen and (min-width: 30em) {
p {
font-size: 18px;
}
a {
text-decoration: underline;
}
}
Capire i framework di utilità CSS
L’approccio di incapsulare le media query CSS all’interno delle regole di stile di un elemento ed elaborarle tramite il processore CSS è piuttosto efficiente. Tuttavia, questo costringe ancora lo sviluppatore a passare continuamente tra i livelli HTML e CSS. C’è anche la necessità di assegnare nomi di classe univoci agli elementi in HTML. La logistica risultante porta a una sgradita complessità. È qui che entrano in gioco i framework di utilità CSS, una tecnologia influente al giorno d’oggi.
Un framework di utilità CSS collega le proprietà CSS atomiche ai breakpoint. Le classi CSS risultanti possono essere assegnate a qualsiasi elemento nell’HTML. Questo permette di definire layout e componenti reattivi solo in HTML, senza bisogno di usare codice CSS. L’uso di un framework di utilità CSS consente una rapida prototipazione ed è perfetto per lo sviluppo di componenti. È per questa ragione che i framework di utilità CSS vengono spesso impiegati in combinazione con tecnologie orientate ai componenti, come React e Vue.
Consideriamo un altro esempio preso in prestito dal framework di utilità CSS Tachyons. Date un’occhiata al seguente codice CSS. Definiamo innanzitutto classi da ‘mw1’ a ‘mw3’ che limitano la larghezza massima di un elemento qualsiasi ai valori compresi tra ‘1rem’ e ‘3rem’. Inoltre, definiamo all’interno dei breakpoint già presentati, ‘medium’ e ‘large’, le corrispondenti classi CSS, che contengono l’abbreviazione del rispettivo breakpoint nel loro nome:
/* Tachyons */
/* Dimensione Mobile first */
.mw1 { max-width: 1rem; }
.mw2 { max-width: 2rem; }
.mw3 { max-width: 3rem; }
/* Breakpoint 'medium' */
@media screen and (min-width: 30em) and (max-width: 60em) {
.mw1-m { max-width: 1rem; }
.mw2-m { max-width: 2rem; }
.mw3-m { max-width: 3rem; }
}
/* Breakpoint 'large' */
@media screen and (min-width: 60em) {
.mw1-l { max-width: 1rem; }
.mw2-l { max-width: 2rem; }
.mw3-l { max-width: 3rem; }
}
Grazie a queste classi CSS possiamo scrivere elementi reattivi totalmente in HTML. Il seguente frammento di codice HTML definisce un’immagine che ha una larghezza massima di ‘1rem’ su schermi piccoli. L’immagine si adatta automaticamente alla larghezza disponibile sullo schermo. Su schermi di medie dimensioni l’elemento accetta un massimo di ‘2rem’, su schermi grandi un massimo di ‘3rem’.
<img class="mw1 mw2-m mw3-l" src="/immagine.png" alt="Un’immagine responsive">
I framework di utilità CSS definiscono un grande insieme di classi atomiche e ogni classe specifica solo una proprietà CSS. Oltre alle dimensioni di un elemento, si tratta di informazioni sulla tipografia, la colorazione e pressoché ogni altra proprietà possibile. Per ogni proprietà atomica, un framework di utilità CSS contiene classi per ciascun breakpoint definito. Combinando diverse classi, quasi tutti gli elementi completamente reattivi possono essere uniti.
Il framework Tachyons descritto sopra è in circolazione da diversi anni e non viene più sviluppato attivamente. Tuttavia, per via della sua relativa semplicità, vale la pena prendere in considerazione Tachyons per imparare il responsive web design. Il modo più semplice per capire è osservare i componenti di Tachyons. Questi sono elementi di esempio che sono definiti esclusivamente usando classi di utilità.
Il successore spirituale di Tachyons è la sua variante moderna, TailwindCSS, che offre alcuni vantaggi rispetto a Tachyons. Il progetto è inoltre sviluppato attivamente e supporta molti sistemi di sviluppo front end popolari. Inoltre, TailwindCSS può essere completamente personalizzato per le esigenze specifiche di un progetto. Tutte le preimpostazioni come i breakpoint, la scala delle dimensioni dei caratteri e simili possono essere configurate facilmente.
Per quanto i framework di utilità CSS siano utili per lavorare, hanno anche un grande svantaggio: può essere necessario un grande insieme di classi atomiche per definire un elemento. Inoltre, per impostazione predefinita, il file di codice sorgente CSS contiene classi per tutte le combinazioni di valori di proprietà CSS e breakpoint. Nel caso di TailwindCSS ci sono migliaia di classi, il che provoca un aumento di diversi megabyte delle dimensioni del file CSS non compresso, uno stato insostenibile dal punto di vista delle prestazioni.
Fortunatamente TailwindCSS vi pone rimedio in due modi. Da un lato, il framework riconosce l’istruzione ‘@apply’, che è usata per riunire sotto un nuovo nome di classe le combinazioni di classi di utilità usate ripetutamente. Dall’altro, TailwindCSS supporta PurgeCSS, uno strumento usato come parte del processo di compilazione per rimuovere qualsiasi classe di utilità inutilizzata dalla compilazione di produzione. PurgeCSS elabora i modelli HTML del progetto e include solo le classi CSS trovate nel file di codice sorgente CSS generato. Questo riduce la dimensione del file di codice sorgente a un livello accettabile.