Media queries

22 settembre 2014

Con le media queries possiamo specificare differenti set di proprietà da applicare a seconda che il device dell’utente risponda a particolari caratteristiche, come ad esempio la dimensione dello schermo o la densità di pixel.

Le media queries sono alla base di molte tecniche per il responsive web, ad esempio servono a trasformare un menu da orizzontale a verticale quando si scende al di sotto di una dimensione minima dello schermo. Ecco un esempio (utilizza la barra di trascinamento centrale per simulare uno schermo di piccole dimensioni):


<ul class="menu">
  <li><a>Home<a/></li>
  <li><a>Chi siamo<a/></li>
  <li><a>Contatti</a></li>
</ul>
/* file SCSS */

.menu li{
  display: inline-block;
  padding: 10px;
  border-right: 1px solid black;
}
.menu li:first-child{
  border-left: 1px solid black;
}

@media screen and (max-width: 300px){
  .menu li{
    display: block;
    text-align: center;
    background: gray;
  }
  .menu li:first-child{
    border-left: none;
  }
}

Il problema di questo genere di interventi è tutto legato alla mantenibilità del CSS prodotto, diventa difatti difficile, con l’aumentare del codice, tenere traccia delle proprietà di un oggetto della pagina se queste sono sparse tra diverse contenitori @media in un foglio di stile con centinaia, o migliaia, di righe.

Fortunatamente SASS introduce la possibilità di nidificare @media all’interno del selettore, creando così la possibilità di mantenere tutte le proprietà dello stesso oggetto vicine fra di loro con conseguente miglioramento della mantenibilità e della leggibilità del documento, ecco l’esempio precedente riscritto in salsa SASS. (provalo online)

/* File SCSS */

.menu{
  li{
    padding: 10px;
    @media screen and (max-width: 320px){
      display: block;
      text-align: center;
      background: gray;      
    }
    @media screen and (min-width: 321px){
      display: inline-block;
      border-right: 1px solid black;    
      &:first-child{
        border-left: 1px solid black;
      }
    }    
  }
}

Acquisita questa nuova abilità, possiamo combinarla con quanto già visto nelle pagine precedenti della guida, per risolvere in modo interessante un problema comune degli ultimi anni: la gestione delle immagini di background sui display retina.

Sappiamo che per avere un buon supporto retina dovremmo implementare un set di proprietà come le seguenti per ogni selettore interessato:

.logo {
	background-image: url("logo.png");
}

@media print,   
(-webkit-min-device-pixel-ratio: 1.25),
(-o-min-device-pixel-ratio: 5/4),
(min-resolution: 120dpi)
{
	.logo {
		background-image: url("logo@2x.png");
		background-size: 100px 50px;  /* 50% della dimensione reale dell’immagine @2x */
	} 
}

Seppur perseguibile, questa tecnica porta quasi inevitabilmente a risultati molto confusionari, con l’aiuto di un buon @mixin possiamo semplificare di molto il problema come segue:

@mixin retinafy() 
{
	@media print,
	(-webkit-min-device-pixel-ratio: 1.25),
	(-o-min-device-pixel-ratio: 5/4),
	(min-resolution: 120dpi)
	{
		@content;
	}
}

.logo
{
	background-image: url("logo.png");

	@include retinafy
	{
		background-image: url("logo@2x.png");
		background-size: 100px 50px;
	} 
}

@at-root

L’esempio precedente potrebbe rivelare un ‘lato oscuro’, la direttiva @mixin infatti viene tradotta come un nuovo blocco CSS ad ogni invocazione: significa che se abbiamo 100 selettori che devono essere essere abilitati al supporto retina, otteniamo un CSS contenente 100 copie della direttiva @media, quando in realtà avremmo potuto ottimizzare di molto la dimensione del CSS raggruppando tutti i vari selettori all’interno di un’unico contenitore @media.

Per poter ottenere questo effetto e beneficiare dell’eleganza derivante dall’avere tutte le proprietà dell’oggetto all’interno dello stesso, dobbiamo avvalerci di un’altra interessante direttiva: @at-root: ogni proprietà inclusa in questa direttiva verrà stampata nel CSS prodotto all’esterno della normale nidificazione SASS.

facciamo un esempio comparando un frammento di codice SASS con il risultante CSS (provalo online):

// File SCSS

div {
	border: 1px solid red;
	
	p {
		color: red;
	}

	@at-root p {
		color: green;
	}
}
/* CSS risultante */

div {
	border: 1px solid red;
}

div p {
	color: red;
}

p {
	color: green;
}

Anche se l’esempio non brilla nel mostrare una situazione in cui questa direttiva sia di qualche utilità ne evidenza il comportamento. Possiamo ulteriormente affinare @at-root con due parametri, with o without, per specificare esattamente quali selettori vogliamo siano rimossi (o mantenuti) nella catena di nidificazione.

Utilizzando in modo sapiente questa direttiva possiamo raggiungere il nostro scopo prefissato, è sufficiente raggruppare tutti i selettori interessati dal supporto ai display retina all’interno della media query di cui sopra e poi utilizzare la direttiva @at-root per specificarne il comportamento in presenza schermi con densità di risoluzione standard:

@media print,   
(-webkit-min-device-pixel-ratio: 1.25),
(-o-min-device-pixel-ratio: 5/4),
(min-resolution: 120dpi)
{ 
	.logo
	{
		@at-root(without: media) {
			background-image: url("logo.png");
		}
		
		background-image: url("logo@2x.png");
		background-size: 100px 50px; 
	}
}

In questo modo possiamo beneficiare sia dell’eleganza derivante dall’avere tutte le proprietà all’interno dello stesso selettore padre, sia del minore peso del CSS risultante la compilazione.

Tutte le lezioni

1 ... 11 12 13 ... 18

Se vuoi aggiornamenti su Media queries inserisci la tua e-mail nel box qui sotto:
Tags:
 
X
Se vuoi aggiornamenti su Media queries

inserisci la tua e-mail nel box qui sotto:

Ho letto e acconsento l'informativa sulla privacy

Acconsento al trattamento di cui al punto 3 dell'informativa sulla privacy