Frontend

Come usare le media queries in CSS

Autore

Manuel Ricci

Le media queries, quando vennero introdotte in CSS ricordo di essere tipo impazzito perché avevo ben inteso l’enorme potenziale dietro questa at-rule, nello specifico la at-rule @media.

Ma cosa sono esattamente le media queries? Beh come appena scritto stiamo parlando di una at-rule di CSS che può essere usata per applicare degli stili in base al risultato di una media query.

Alcuni esempi di media queries che abbiamo a disposizione sono:

  • Dimensione del viewport
  • Orientamento dello schermo
  • Preferenze di sistema (schema colore, riduzione delle animazioni, ecc.)
  • Tipo di puntatore
  • Supporto ad hover

I tre elementi principali delle media queries sono il tipo di media, la funzionalità e gli operatori logici.

Tipi di media

Per tipo di media si intendono:

  • print: gli stili vengono applicati durante la stampa
  • screen: gli stili vengono applicati nelle visualizzazioni su schermo
  • all: gli stili vengono applicati ovunque (valore di default)

Con valore di default si intende che può anche essere omesso e verrà comunque considerato come all a meno che non si specifichi diversamente.

Le funzionalità

Le funzionalità invece sono parecchie e ci permettono di applicare gli stili in determinate situazioni, come quelle menzionate in precedenza. Più avanti nell’approfondimento vedremo meglio qualche esempio, ma il consiglio è quello di leggersi la documentazione completa di @media su MDN.

Operatori logici nelle media query

Con gli operatori logici invece possiamo combinare le varie media queries creandone alcune veramente molto complesse, per quanto il consiglio generale sia sempre quello di prediligere la semplicità.

Media queries e accessibilità

Ci sono alcune media queries come prefers-reduced-motion o prefers-contrast che permettono di applicare gli stili in base alle preferenze dell’utente. Nel primo caso qualora avesse impostato il proprio dispositivo affinché le animazioni vengano ridotte abbiamo la possibilità di disabilitare o limitare le animazioni nel nostro sito o web application. Nel secondo caso invece si possono cambiare gli stili per coloro che hanno impostato il proprio dispositivo con alto contrasto.

Alcuni esempi di media query

Nei prossimi giorni il nostro markup è molto semplice:

1<div class=”box”></div>

Lo arricchiremo successivamente con un altro paio di cose, ma per ora va bene così.

Di base invece il CSS è il seguente:

1html {
2  font-family: Arial, Helvetica, sans-serif;
3}
4
5.box {
6  width: 100px;
7  height: 100px;
8  background: tomato;
9  overflow: hidden;
10  position: absolute;
11  border-radius: 10px;
12  top: 50%;
13  left: 50%;
14  transform: translate(-50%, -50%);
15}
16
17.box::after {
18  content: "";
19  color: #fff;
20  background-color: rgb(0 0 0 / 50%);
21  position: absolute;
22  top: 0;
23  left: 0;
24  width: 100%;
25  height: 100%;
26  text-align: center;
27  padding: 10px 0;
28}

display-mode

display-mode può essere utilizzata per applicare degli stili in base alla modalità di visualizzazione del sito o web app. I valori possibili sono i medesimi di quelli utilizzabili nel web manifest di una PWA.

  • fullscreen
  • standalone
  • minimal-ui
  • browser
  • window-controls-overlay
1@media (display-mode: fullscreen) {
2  .box::after {
3    content: "Fullscreen";
4  }
5}

pointer

pointer permette di verificare il tipo di puntatore disponibile. Per puntatore si intendono dispositivi come il mouse o le nostre dita. I valori possibili sono:

  • none
  • coarse
  • fine
1@media (pointer: coarse) {
2  .box::after {
3    content: "Touch";
4  }
5}

hover

Ci sono siti web che fanno affidamento all’hover per poter creare certe animazioni, ma su dispositivi mobili un vero e proprio hover non c’è e quindi si può decidere di optare per cambiare completamente aspetto o interazione con l’uso della media feature hover. I valori possibili sono:

  • none
  • hover
1@media (hover: hover) {
2  .box:hover::after {
3    content: "Mouse";
4  }
5}
6
7@media (hover: none) {
8  .box::after {
9    content: "No Mouse";
10  }
11}

orientation

Permette di testare l’orientamento del viewport. I valori possibili sono:

  • portrait
  • landscape
1@media (orientation: landscape) {
2  .box::after {
3    content: "Landscape";
4  }
5}

Facciamo qualcosina di più qui aggiungere questo <div> prima della chiusura di <body>:

1<div class="only-for-landscape">
2  <p>Ruota il tuo dispositivo per poter vedere questo contenuto</p>
3</div>

In CSS possiamo scrivere questo:

1@media (width <= 768px) and (orientation: portrait) {
2  .only-for-landscape {
3    display: block;
4    position: absolute;
5    top: 0;
6    left: 0;
7    width: 100%;
8    height: 100%;
9    text-align: center;
10    background-color: rgb(255 255 255 / 70%);
11    backdrop-filter: blur(10px);
12  }
13
14  .only-for-landscape p {
15    position: absolute;
16    top: 50%;
17    left: 50%;
18    transform: translate(-50%, -50%);
19    width: 90%;
20    font-size: 1.5rem;
21    color: #000
22  }
23}

In questo caso ci sono da notare giusto qualcosina:

  • la media query usa anche width che ci permette di definire anche la dimensione del viewport
  • abbiamo usato and per creare una condizione logica dove entrambe le media queries devono essere vere
  • abbiamo usato backdrop-filter per creare lo sfondo sfocato
  • abbiamo usato transform per centrare il testo nel div

prefers-color-scheme

Permette di determinare se l’utente ha espresso delle preferenze a livello di sistema sul tipo di schema colore preferito. I valori possibili sono:

  • light
  • dark
1@media (prefers-color-scheme: dark) {
2  body {
3    background-color: #000;
4    color: #fff;
5  }
6
7  .box {
8    background: rgb(250, 163, 148);
9  }
10
11  .box::after {
12    background-color: rgb(0 0 0 / 20%);
13  }
14}

prefers-reduced-motion

Come già menzionato in precedenza permette di determinare se l’utente ha espresso delle preferenze a livello di sistema sulle animazioni. I valori possibili sono:

  • no-preference
  • reduce

Al nostro div .box aggiungiamo una classe animate:

1<div class="box animate"></div>

In CSS scriviamo:

1.animate {
2  animation: pulse 1s infinite both;
3  transform-origin: center center;
4}
5
6@keyframes pulse {
7  0% {
8    scale: 1;
9  }
10
11  50% {
12    scale: 1.1
13  }
14
15  100% {
16    scale: 1;
17  }
18}
19
20@media (prefers-reduced-motion: reduce) {
21  .animate {
22    animation: none;
23  }
24}

Chiaramente non è sempre necessario rimuovere completamente le animazioni è possibile anche ridurle soltanto o limitare.

print

In questi ultimi esempi voglio farti vedere il media type print in azione.

1@media print {
2  .box::after {
3    content: "Print";
4  }
5}
6
7@media not print {
8  .box::after {
9    content: "Not Print";
10  }
11}

Per poter vedere quel Print nel box basta provare ad avviare la stampa ( Ctrl/Cmd + p) per vedere che gli stili vengono cambiati.

La seconda media query è negata, ciò significa che si applicherà agli screen, not indica sempre il contrario.

Caricamento...

Diventiamo amici di penna? ✒️

Iscriviti alla newsletter per ricevere una mail ogni paio di settimane con le ultime novità, gli ultimi approfondimenti e gli ultimi corsi gratuiti puubblicati. Ogni tanto potrei scrivere qualcosa di commerciale, ma solo se mi autorizzi, altrimenti non ti disturberò oltre.

Se non ti piace la newsletter ti ricordo la community su Discord, dove puoi chiedere aiuto, fare domande e condividere le tue esperienze (ma soprattutto scambiare due meme con me). Ti aspetto!

Ho in previsione di mandarti una newsletter ogni due settimane e una commerciale quando capita.