HTML

Images responsive et attribut sizes, amstramgram, pic...

Article par (Designer Web & Mobile spécialisée en UI and UX design, Partout dans le monde :))
Créé le , mis à jour le (45975 lectures)
Tags : images, responsive, srcset, sizes

Résumé de l’épisode précédent : avec Geoffrey, nous avons vu qu’il est désormais possible d’avoir plusieurs sources de différente taille pour une image grâce à l’attribut srcset. En version tl,dr; on utilise l'attribut srcset pour donner au navigateur une liste d'images, on renseigne la taille de chacune avec le descripteur w, le navigateur se débrouille (oui se débrouille, littéralement c'est lui qui choisit) pour afficher l'image la plus appropriée en fonction de différents critères : tailles de la fenêtre de navigation, résolution de l'écran, voire pourquoi pas bande passante et âge du capitaine ?

Et parce que je vous connais, voici un gros disclaimer :

Attention ce qui suit fait partie d'une spécification en cours de rédaction à la date du 9 mars 2015. Elle peut encore évoluer. Ce n'est pas encore implémenté sur tous les navigateurs. Nous vous conseillons Chrome Canary ou Firefox Nightly pour tester.

Dans le code, ça ressemble à ça :

<img src="medium.jpg"
     srcset="small.jpg 340w,
             medium.jpg 680w,
             large.jpg 1024w"
     alt="kiwi">

Démonstration

Dans la mesure où le cache de Chrome est plutôt persistant, nous vous conseillons pour tester de charger la page en petite largeur, agrandir et observer les changements d'image. Vous pouvez aussi consulter cette vidéo de démo.

Les limites de cette technique

Cette technique est bien pratique, mais on n'a pas forcement toujours besoin de charger la plus large version de l'image. Quand on commence à faire des mises en page en colonne par exemple, parfois une version plus petite pourrait suffire. Par exemple, à 1024px de large, si mon image fait 50% de la taille du navigateur, je n'ai pas forcément besoin de charger une grosse image de 1024px de large : 

C'est là où l'attribut sizes="" va entrer en action. Cet attribut permet de spécifier des tailles d'image affichées en fonction de différents points de rupture. 

L'attribut sizes="" en action

Dans ma nouvelle version de ma page, j'ai 3 versions de gabarits de mise en page grâce à flexbox :

  • sur petits écrans l'image fait toute la largeur, le texte est en-dessous,
  • à partir de 600px l'image et le texte font tous deux 50%,
  • à partir de 980px, l'image occupe 30% et le contenu 70%.

3 gabarits de mise en page

 

Démonstration

Là encore pour tester, commencez par charger en petit, augmentez la taille et si vous voulez tester à une taille précise il va vous falloir vider le cache.

Je peux dois* donc spécifier dans un attribut sizes ces différentes largeurs d'affichage  "souhaitées" de image à mon navigateur de la manière suivante : 

  <img src="medium.jpg"
     srcset="small.jpg 340w,
             medium.jpg 680w,
             large.jpg 1024w"
     sizes="(min-width: 600px) 50vw , (min-width: 980px) 30vw , 100vw"
     alt="kiwi">

Ici, j'ai spécifié à mon navigateur que l'image sera affichée sur la moitié du navigateur si la zone d'affichage fait plus de 600px, qu'elle prendra 30% du navigateur si la zone d'affichage fait plus de 980px, et dans tous les autres cas (ici sous 600px), elle prendra 100% de la largeur du navigateur. Vous pouvez bien sûr utiliser des pixels, des em, des pourcentages ou n'importe quelle autre unité ici.

*Petite mise à jour du 4 mai 2015 : l'attribut "sizes" est désormais obligatoire quand on utilise srcset et des descripteurs w

Amstramgram pic et pic choisis celle qui te plait le plus

C'est là où ça devient drôle (ou pas), le navigateur va choisir l'image qui lui convient le mieux et faire les optimisations tout seul. Voici donc une petite comparaison de deux versions de Chrome 40, en haut Canary 43, en bas la version 40. 

comparaison de chargement d'image avec sizes entre chrome 40 et canary 43

Sur très petit écran les deux sont d'accord et chargent la version small de l'image. Par contre sur grand écran Chrome 40 charge la version large alors que Canary la version medium. Pour le coup c'est Canary qui est le plus malin, en théorie ici on n'aurait pas besoin d'une image qui fait 1024px de large même si le navigateur en fait plus de 1280, puisque mon image est affichée à 1/3 du gabarit.

Le truc fun (ou pas) : sur mon Android Nexus 5 qui a un écran hdpi en 4G, il me charge la version 1024px. Je suppose que c'est à cause de la résolution "HD" de l'écran, il tente donc de me charger une image de qualité. A tester s'il est capable quand j'ai une connexion plus lente de charger une image plus petite ou s'il n'est pas encore assez malin pour ça.

En pratique, cela signifie qu'on va commencer à faire pas mal d'allers-retours entre nos gabarits de page et nos media-queries dans le CSS pour ne pas se retrouver avec des listes monstrueuses d'images. Je vous laisse lire Keeping srcset and sizes under control si le processus vous intéresse.

En résumé 

Vous définissez des tailles réelles d'images et des tailles d'affichage de ces images en fonction de vos gabarits, puis vous laissez faire le navigateur. Vous n'avez à partir de là plus aucun contrôle sur ce que le navigateur choisit de charger, c'est lui qui optimise selon ses critères.

L'autre nouvelle sympathique, c'est que l'on va pouvoir combiner srcset avec la nouvelle balise picture qui va permettre de charger différentes images pour accommoder les besoins de la direction artistique. De quoi prévoir un joyeux petit méli-mélo dans les années à venir.

Alors, happy ? :)

Ressources

Commentaires

Nico3333fr a dit le

Même si je comprends l'idée, le besoin et la technique (d'ailleurs, merci de contribuer à éclaircir tout cela ;) ), je ne peux m'empêcher de me demander si on ne se fourvoie pas un peu en rentrant dans le cas « 1 image pour 1 cas ».

J'espère que de nouveaux formats d'image plus performants viendront contribuer à réduire cette future profusion de versions…
(et vive SVG quand on peut !)

Stéphanie W. a dit le

@Nico3333fr : Effectivement si tu lis l'article "Keeping srcset and sizes under control" tu verra qu'il propose de faire le tri à la fin, et retirer les formats d'images qui semblent trop proches pour ne pas avoir trop de choses à gérer. Et comme souvent, c'est parce qu'on peut, qu'il faut. Enfin, qu'on pourra.

Nilav_ a dit le

Je n'ai pas encore lu l'article auquel tu fais référence mais dans de nombreux cas, j'avoue que j'imagine peu de situations où je dépasserai 3 tailles.
Par contre, il me vient une question, peut-on adapter ce comportement (une image, plusieurs tailles) à un système type lightbox quand dans ce cas nous souhaitons être JavaScript proof. En effet, pour une de mes lightbox, j'utilise l'attribut rel pour indiquer au JavaScript l'URL de l'image à piocher. Si JS désactivé, mon visiteur au clic sur la miniature est redirigée vers une vraie page du site avec l'image source. L'idée est de lui éviter d'aller directement sur le lien de l'image. Dans le cas JS désactivé c'est facile de placer les différentes tailles. Mais dans le cas avec lightbox je me dis que ce serait pertinent d'avoir différentes tailles fonctionnelles, d'autant plus que nous sommes théoriquement dans un contexte favorisant la consultation en album.

samIntegrateur a dit le

Merci pour cet article, cela fait un moment que je m'interroge sur la façon d'utiliser cela, mais je ne savais pas qu'en plus les navigateurs faisaient des choix différents...

J'ai également été intéressé par un système comme celui décrit ici : http://www.smashingmagazine.com/2015/02/24/ri...

Mais cela reste encore très imparfait puisqu'on ne gère pas l'attribut "sizes". Mon point de vue c'est que c'est effectivement excitant d'avoir des images adaptées, mais pour la mise en pratique "industrialisée", tout reste encore à inventer.

Nico-Semaphore a dit le

Reste à voir l'implantation (ou pas) dans les backoffice des CMS pour permettre aux rédacteurs/utilisateurs de saisir les 1->x images nécessaires voire les point-break associés pour leur permettre de bien maitriser leur création de contenu. Après une très rapide réflexion je pense que ce n'est pas près d'arriver (si déjà ils remplissaient le alt systématiquement...)

wezer a dit le

@Nico-Sema"<b>sphore : <b>pasmal

Derwoed a dit le

Bonjour.

Je viens de lire vos 2 très intéressants articles (http://www.alsacreations.com/article/lire/1621-responsive-images-srcset.html et celui-ci) et ayant un peu de temps j’ai voulu faire quelques tests, en commençant avec la balise <img>. Malheureusement, soit je n’ai pas compris grand chose, soit la valeur "w" de srcset est super mal gérée, même par les dernières versions de navigateurs. J’ai ouvert un fil sur le forum (http://forum.alsacreations.com/topic-2-78139-1-Valeurwdesrcsetoucommentdevenirfou.html) avec une adresse CodePen de test, mais les réponses ne se bousculent pas. Si un "savant" passe par ici et peu faire un tout là-bas je lui en serrait très reconnaissant (ainsi que d’autres participant au forum sans doute…).