SRCSET

Ok, abbiamo visto quali sono le condizioni nelle quali parliamo di immagini responsive.
Il primo caso che prendiamo in esame, che è anche quello più semplice, è quello dove l'immagine non cambia di proporzioni ma solo di dimensioni.

Dimensioni diverse, proporzioni uguali

Quindi la stessa immagine di 2PAC prima è piccola, poi è grande.

L'immagine è la stessa. Nel caso di un viewport piccolo, è rettangolare piccola. Nel caso di un viewport grande, è la stessa immagine rettangolare però grande.

SRCSET for the win

Soluzione: l'attributo srcset.
L'attributo srcset va aggiunto al classico tag img. Esempio:

<img src="tupac.jpg" alt="Tupac"/>  

Aggiungiamo l'attributo srcset all'interno del quale mettiamo un serie di coppie [path a immagine] [relative dimensioni]

Esempio:

<img  
    srcset="[email protected] 3x, 
            [email protected] 2x, 
            tupac.jpg 1x"
    src="tupac.jpg" 
    alt="Tupac"/>

In questo caso abbiamo anticipato al browser che la prima immagine è al tripo della densità di pixel (3x), poi ne abbiamo una al doppio della densità (2x) e infine la non-retina (1x).

Liberto arbitrio anche per i browser

In soldoni quello che stiamo facendo è lasciare al browser la possibilità di scelta. Il browser valuterà le risorse a disposizione, il contesto in cui opera, e infine sceglierà la risorsa che ritiene più adatta.

Quello che succede è più o meno questo (lo romanzo un po'):

  • "Ok fratè, devo visualizzare quest'immagine di 2pac"
  • "Hey ma vedo che abbiamo risorse aggiuntive a quella classica! Fico! Io so che sono in un display retina, vediamo cosa abbiamo tra le risorse extra..."
  • "Sòccia! La prima immagine è addirittura al tripo della densità. Sono fico ma non così tanto, forse è troppo. Vediamo se c'è altro."
  • "Guarda mo', c'è un'immagine retina 2x. Preferisco questa a quella classica. Scarico questa."

Il nostro amico browser ha valutato le risorse disponibili e ha scelto quella secondo lui più adatta. La cosa fica è che noi non dobbiamo preoccuparci di nulla. E ancora più fico è che se domani aumentano le variabili in gioco noi comunque non dobbiamo preoccuparci di niente. Tipo che se se magicamente domani il browser dovesse considerare anche che velocità di banda che abbiamo a disposizione, o se siamo in roaming all'estero e quindi ogni bite che scarichiamo ci costa tanti $$$, deciderà lui da solo quale immagine è più consona. Noi non dobbiamo preoccuparci.
...Non è bellissimo?

Un po' più difficile

L'esempio appena fatto era un pochino semplificato.
Le immagini infatti possono essere differenziare per dimensione e non solo per densità di pixel. Ad esempio:

<img  
    srcset="tupac-retina-360.jpg 360w, 
            tupac-retina-540.jpg 540w, 
            tupac-retina-720.jpg 720w, 
            tupac-retina-960.jpg 360w"
    src="tupac.jpg" 
    alt="Tupac"/>

In questo caso abbiamo quattro immagini e ugnuna di esse occupa il numero espresso in w, che sta per width.
Quindi tupac-retina-360.jpg occupa 360px e così via.

Schermi più grandi non vogliono per forza immagini più grandi

Nel post precedente ho detto che a schermi più grandi non è detto che corrispondano immagini più grandi. Non scherzavo: il browser nel momento in cui carica l'immagine non sa quanto occuperà quell'immagine nel layout.
Perché? Perché non sa ancora come sarà il layout.
Perché? Perché non ha ancora scaricato il CSS.
Perché? Perché per essere più veloce scarica prima le immagini poi il resto.
In una parola: Preload.

Size matters

Ed ecco che ci sono le size a risolvere il problema.
L'attributo size non fa altro che anticipare al browser quanto occuperanno le immagini all'interno del layout. Glielo dice in chiaro senza che il browser debba calcolare tutto il css.

La cosa si complica un pochino, ma neanche troppo:

<img  
    srcset="tupac-retina-360.jpg 360w, 
            tupac-retina-540.jpg 540w, 
            tupac-retina-720.jpg 720w, 
            tupac-retina-960.jpg 360w"
    size="(min-width: 900px) 32vw,
          (min-width: 700px) 50vw,
          100vw"
    src="tupac.jpg" 
    alt="Tupac"/>

All'interno di size ci sono una serie di coppie (condizione) dimensione dove, al verificarsi di quella condizione => l'immagine ha quella dimensione.
Nel nostro esempio: da 900px in su (min-width: 900px), l'immagine sarà larga il 32% del viewport width (32vw, dove vw sta per viewport-width).
Da 700px in su, quindi fino a 900px, l'immagine sarà larga il 50% del viewport.
Infine, se il viewport è più piccolo di 700px, l'immagine sarà al 100%.

In questo caso il browser considera le risorse a disposizione, legge le size, e sceglie.
Come sceglie? La prima condizione valida viene presa per buona.

Quindi tornando al nostro 2pac, il ragionamento del browser si aggiornerà più o meno a questa versione (facciamo finta che questa volta non sia retina):

  • "Ok compà, devo visualizzare sempre quest'immagine di 2pac"
  • "Hey hey hey, vedo che abbiamo immagini aggiuntive a quella classica. Vediamo cosa abbiamo tra le risorse extra"
  • "Apperò!, ne abbiamo parecchie. Mi dicono le dimensioni che occuperà Tupac in pagina. Oggi è il mio giorno fortunato"
  • "Vediamo: io sono largo 760px, quindi non mi interessa il caso da 900px in su. Mi interessa piuttosto il caso subito dopo, quello da 700px in su, fino a 900px"
  • "L'immagine che mi spetta non è quella da 32vw, ma quella da 50vw. Anzi, posso già dire che occuperà il 50% di 760px, quindi 380px. Ok, posso dire che Tupac occuperà 380px"
  • "Controllando le immagini a disposizione... direi che tupac-retina-360.jpg 360w è quella più adatta. I 20px che mancano li copro allargandola un pochino"

L'ultimo punto in particolare è quello che potrebbe cambiare da browser a browser. È fuori controllo ma è una particolarità che deve essere vista come un bene. Come dicevo sopra: oggi un browser considera solo la larghezza dello schermo. Magari domani considererà altri aspetti. Lasciamo a lui la scelta.

Conclusioni

In sintesi:

  1. parti dal classico tag <img>,
  2. elenchi le immagini che hai a disposizione dichiarando le dimensioni di ognuna di esse,
  3. descrivi con le media query quanto spazio occuperanno le immagini all'interno del layout

Con questi tre passaggi hai ottenuto che gli utenti con browser "meno fortunati" leggano comunque il buon vecchio tag img. Tutti gli altri ricevono l'immagine più adatta al prorio contesto.
Quale immagine in particolare non ci interessa.

Semplice, efficace, future friendly.

Il prossimo caso di immagine resposive sarà invece relativo a quando DOBBIAMO avere il controllo delle immagini e vogliamo scegliere noi quale usare.