Dans cet article, nous allons préciser le concept d'images adaptatives — images qui s'adaptent aux appareils selon les différentes tailles d'écran, résolutions et autres caractéristiques de ce type — et examiner les outils fournis par HTML pour faciliter leur mise en œuvre. Les images adaptatives ne sont qu'une part (elles préparent le terrain) dans la conception de sites Web adaptatifs, sujet sur lequel vous en apprendrez beaucoup plus dans un futur module au sujet des CSS.

Prérequis : Vous devriez savoir comment créer un document HTML simple et comment ajouter des images statiques à une page web.
Objectifs : Apprendre comment utiliser des fonctionnalités comme srcset et l'élément <picture>  pour implémenter des solutions d'images adaptatives sur les sites Web.

Pourquoi des images adaptatives ?

Quel problème essayons-nous de résoudre avec des images adaptatives ? Examinons un scénario typique. Un site Web classique a probablement une image d'en-tête pour flatter le regard du visiteurs, plus peut-être quelques images de contenu plus loin. Vous voulez probablement que l'image d'en-tête couvre toute la largeur de l'en-tête et que l'image de contenu s'insère quelque part à l'intérieur de la colonne de contenu. Voyons un exemple simple :

Our example site as viewed on a wide screen - here the first image works ok, as it is big enough to see the detail in the center.

Cela fonctionne bien sur un appareil avec un grand écran, comme un portable ou un ordinateur de bureau (vous pouvez voir cet exemple en direct et trouver son code source sur Github). Nous ne nous attarderons pas sur les CSS, excepté pour préciser ceci :

  • Le contenu du corps a été fixé à une largeur maximale de 1200 pixels — dans les fenêtres de largeur supérieure, il s'affiche sur 1200 px et se centre dans l'espace disponible. Dans celles de largeur inférieure, le contenu occupe 100% de la largeur de la vue.
  • L'image d'en-tête est définie de sorte que son milieu soit toujours au centre de l'en-tête, quelle que soit sa largeur. Ainsi, si le site est regardé sur un écran moins large, le détail important au centre de l'image (les gens) peut toujours être vu, et l'excès est perdu de part et d'autre. L'image a une hauteur de 200 px.
  • Les images de contenu sont définies de sorte que si l'élément corps devient plus petit que l'image, les images se contractent pour rester toujours à l'intérieur du corps sans jamais déborder.

Tout cela c'est très bien, mais le problème vient quand vous commencez à regarder le site sur un écran étroit — l'en-tête semble correct, mais commence à prendre beaucoup de hauteur pour un mobile, et la première image de contenu d'autre part n'est pas terrible — à cette taille, vous avez du mal à distinger les personnes !

Our example site as viewed on a narrow screen; the first image has shrunk to the point where it is hard to make out the detail on it.

Quand le site est vu sur un écran étroit, il serait préférable de montrer une version recadrée de l'image sur les parties importantes de la vue au lieu de faire voir des bâtisses, et peut-être quelque chose entre les deux pour un écran de largeur moyenne comme une tablette — ce problème relève de décisions de nature artistique.

De plus, il n'est pas nécessaire d'intégrer des images aussi volumineuses sur une page destinée à être affichée sur l'écran minuscule d'un mobile ; c'est le problème des changements de résolution — une image matricielle est définir sur un certain nombre de pixels de large et un certain nombre de pixels de haut ; comme on a pu le voir à propos des graphiques vectoriels, une image matricielle paraît grenue et horrible si elle est affichée plus grande que sa taille d'origine (alors qu'un graphique vectoriel ne l'est pas). Et si elle est montrée significativement plus petite que sa taille d'origine, c'est un gaspillage de bande passante — les utilisateurs de mobiles en particulier ne veulent pas cramer de leur bande passante en téléchargeant une grande image destinée à des ordinateurs de bureau, alors qu'une petite image ferait l'affaire pour leur appareil. La solution idéale serait d'avoir plusieurs résolutions disponibles et de servir des tailles appropriées selon le type d'appareil accédant au site Web.

Pour compliquer encore plus les choses, certains appareils ont des écrans à haute résolution, écrans qui ont besoin d'images plus grandes que ce à quoi on pourrait s'attendre  pour s'afficher correctement. Il s'agit pratiquement du même problème, mais dans un contexte légèrement différent.

Vous pouvez penser que des images vectorielles sont la solution à ces problèmes : elles le sont dans une certaine mesure — elles sont à la fois de petite taille et se mettent à l'échelle : utilisez‑les partout où c'est possible. Mais elles ne conviennent pas à tous les types d'images — parfaites pour des graphiques simples, des motifs, des éléments d'interface, etc., il devient très compliqué de créer une image vectorielle avec le genre de détails que l'on trouve dans une photo, par exemple. Les formats matriciels comme JPEG sont plus adaptés au type d'images affichés dans l'exemple ci-dessus.

Ce type de problème n'existait pas quand le Web a vu le jour, du début jusqu'au milieu des années 90 — à l'époque, les seuls appareils permettant de naviguer sur le Web étaient les ordinateurs de bureau et les portables, de sorte que les ingénieurs et rédacteurs de spécifications pour les navigateurs ne pouvaient même pas imaginer l'existence de ces problèmes. Pour résoudre les problèmes indiqués ci-dessus, les techniques d'images adaptatives sont de mise en œuvre récente : elles offrent au navigateur plusieurs fichiers d'images, soit montrant tous la même chose mais avec un nombre de pixels différent (commutation de résolution), soit des images différentes selon l'espace alloué (décisions artistiques).

Note : Toutes les nouvelles fonctionnalités présentées dans cet article — srcset/sizes/<picture> — sont toutes prises en charge dans les parutions d'explorateurs récemment publiées pour les ordinateurs de bureau et pour les mobiles (y compris l'explorateur Edge de Microsoft,  même si ce n'est pas le cas d'Internet Explorer.) 

Comment créer des images adaptatives ?

 

Dans ce paragraphe, nous allons examiner les deux problèmes illustrés ci-dessus et montrer comment les résoudre à l'aide des fonctions d'images adaptatives du HTML. Notez que nous nous focaliserons sur l'élément <img> du HTML dans cette section, comme vous avez pu le voir dans la zone de contenu de l'exemple ci-dessus — l'image d'en-tête du site n'est là que pour la décoration, et donc implémenté en utilisant des images de fond du CSS. CSS a sans doute de meilleurs outils que le HTML pour la conception adaptative : nous en parlerons dans le module CSS à venir.

Commutations de résolution : tailles différentes

Alors, quel est le problème à résoudre à l'aide des commutations de résolution ? Nous voulons afficher un contenu d'image identique, juste plus grand ou plus petit selon l'appareil — c'est la situation de la deuxième image du contenu de notre exemple précédent. L'élément standard <img> vous permet classiquement de ne faire pointer le navigateur que vers un seul fichier source :

<img src="elva-fairy-800w.jpg" alt="Elva habillée en fée">

Mais il est possible d'utiliser deux nouveaux attributs — srcset et sizes — permettant de fournir plusieurs images source avec des indications pour permettre à l'explorateur de faire le bon choix. Vous trouverez un exemple de cela dans le fichier responsive.html sur Github (voyez aussi le code source) :

<img srcset="elva-fairy-320w.jpg 320w,
             elva-fairy-480w.jpg 480w,
             elva-fairy-800w.jpg 800w"
     sizes="(max-width: 320px) 280px,
            (max-width: 480px) 440px,
            800px"
     src="elva-fairy-800w.jpg" alt="Elva habillée en fée">

Les attributs srcset et sizes paraissent complexes, mais ils ne sont pas difficiles à comprendre si vous les formatez comme indiqué ci-dessus, avec une partie différente de la valeur de l'attribut sur chaque ligne. Chaque valeur contient une liste séparée par des virgules et chaque partie de la liste est composée de trois sous-parties. Passons en revue leur contenu maintenant :

srcset definit l'ensemble des images offertes au choix du navigateur, et la taille de chaque image. Avant chaque virgule, nous avons écrit :

  1. un nom de fichier image (elva-fairy-480w.jpg),
  2. une espace,
  3. la largeur intrinsèque en  pixels (480w) — notez l'utilisation de l'unité w, et non px comme vous auriez pu penser. C'est la taille réelle de l'image; qui peut être trouvée en examinant les propriétés du fichier image sur l'ordinateur  (par exemple sur un Mac, sélectionnez l'image dans le Finder, puis appuyez sur Cmd + I pour faire apparaître l'écran des infos).

sizes définit un ensemble de conditions pour le média (par ex. des largeurs d'écran) et indique quelle taille d'image serait la plus adaptée si certaines conditions sont satisfaites — ce sont les conditions dont nous avons parlé plus haut. Dans ce cas, nous écrivons avant chaque virgule

  1. une condition pour le média ((max-width:480px)) — vous pourrez en savoir plus à ce propos dans l'article sur les CSS, mais pour le moment disons simplement que cette condition pour le média décrit un état possible de l'écran. Dans notre cas, nous disons « si la largeur de fenêtre est de 480 pixels ou moins »,
  2. une espace,
  3. la largeur de la place occupée par l'image si la condition pour le média est vraie (440px).

Note : Pour définir une largeur d'emplacement, vous pouvez indiquer une taille absolue (px, em) ou relative (pourcentage). Vous avez peut‑être noté que la dernière largeur d'emplacement  ne comporte pas d'indication pour le média — c'est la valeur par défaut retenue quand aucune des conditions n'est vraie). L'explorateur ignore tout ce qui suit dès la première condition concordante ; donc soyez attentif à l'ordre de ces conditions pour le média.

Ainsi, une fois ces attributs en place, l'explorateur va :

  1. noter la largeur du périphérique,
  2. vérifier quelle est la première condition vraie pour le média dans la liste des tailles,
  3. noter la largeur d'emplacement demandée par le média,
  4. charger l'image référencée dans la liste srcset qui est la plus proche de la taille choisie.

Et c'est tout ! Donc à ce stade, si un navigateur prenant en charge une largeur de vue de 480 px charge la page, la condition pour le média (max-width: 480px) sera vraie, donc une largeur d'emplacement de 440px sera choisie, donc le fichier elva-fairy-480w.jpg sera chargé, car sa largeur intrinsèque (480w) est celle qui est la plus proche de 440px. L'image 800 px a une taille de 128 Ko sur disque alors que la version 480 px n'occupe que 63 Ko — une économie de 65Ko. Imaginez maintenant qu'il s'agisse d'une page avec beaucoup d'images. L'utilisation de cette technique peut permettre aux utilisateurs de mobiles d'économiser beaucoup de bande passante.

Les explorateurs les plus anciens qui ne prennent pas en charge ces fonctionnalités les ignorent; poursuivent et chargent normalement l'image référencée dans l'attribut src.

Note : Dans l'élément <head> du document, vous trouvez la ligne <meta name="viewport" content="width=device-width"> : ceci force les explorateurs de mobiles de prendre la largeur réelle de leur vue pour charger des pages web (certains explorateurs de mobile mentent à propos de la largeur de leur vue, et à la place chargent des pages pour une vue plus large, puis rétrécissent la page chargée, ce qui n'est pas vraiment une aide pour les pages adaptatives ou pour la conception. Nous vous en dirons plus à ce propos dans un module à venir.)

Outils de développement

 

Il y a quelques outils de développement utiles dans les navigateurs pour vous aider à déterminer les largeurs d'affichage nécessaires, etc, que vous devez utiliser. Pour les déterminer, j'ai d'abord chargé la version non adaptative de l'exemple (not‑responsive.html), puis je suis allé dans Responsive Design View (Outils > Développement Web > Vue adaptative), qui vous permet de regarder les mises en page Web comme si elles étaient visualisées à travers un éventail de tailles d'écran d'appareils différents.

J'ai réglé la largeur de la fenêtre à 320px puis 480px ; pour chacun, je suis allé dans l'inspecteur DOM, j'ai cliqué sur l'élément <img>} qui nous intéresse, puis j'ai regardé sa taille dans l'onglet Box Model View sur le côté droit de l'écran. Cela devrait vous donner les largeurs intrinsèques d'image dont vous avez besoin.

A screenshot of the firefox devtools with an image element highlighted in the dom, showing its dimensions as 440 by 293 pixels.

Ensuite, vous pouvez vérifier si srcset fonctionne en réglant la largeur de la fenêtre sur ce que vous voulez (par exemple une largeur étroite), en ouvrant Network Inspector (Outils > Développement Web > Réseau), puis en rechargeant la page. Ceci devrait vous donner une liste des ressources téléchargées pour dresser la page web, et ici vous pouvez vérifier quel fichier image a été choisi pour le téléchargement.

Note : Utilisez Mozilla Firefox pour tester srcset. Chrome charge la meilleure image dans le cache de l'explorateur, ce qui empêche de la tester dans les outils de développement.

a screenshot of the network inspector in firefox devtools, showing that the HTML for the page has been downloaded, along with three images, which include the two 800 wide versions of the responsive images

Commutation de résolution : même taille, résolutions differentes

Si votre ordinateur prend en charge plusieurs résolutions d'affichage, mais que tout le monde voit l'image avec la même taille effective sur l'écran, vous pouvez permettre au navigateur de choisir une image de résolution appropriée en utilisant srcset avec x-descriptors et sans sizes — une syntaxe un peu plus facile en quelque sorte ! Vous pouvez trouver un exemple de ce à quoi cela ressemble dans srcset-resolutions.html (voir aussi le code source) :

<img srcset="elva-fairy-320w.jpg,
             elva-fairy-480w.jpg 1.5x,
             elva-fairy-640w.jpg 2x"
     src="elva-fairy-640w.jpg" alt="Elva habillée en fée">

A picture of a little girl dressed up as a fairy, with an old camera film effect applied to the imageDans cet exemple, le CSS suivant est appliqué à l'image de façon à ce qu'elle ait une largeur de 320 pixels à l'écran (également nommée pixels CSS) :

img {
  width: 320px;
}

Dans ce cas, sizes n'est pas nécessaire — le navigateur détermine simplement la résolution d'affichage de l'écran et montre l'image la plus appropriée référencée dans srcset. Donc si le dispositif accédant à la page a un affichage standard/basse résolution, avec un pixel de dispositif représentant chaque pixel CSS, l'image elva-fairy-320w.jpg sera chargée (le 1x est implicite, donc vous n'avez pas besoin de l'inclure.) Si le dispositif a une haute résolution de deux pixels de dispositif par pixel CSS ou plus, l'image elva‑fairy-640w.jpg sera chargée. L'image 640px a une taille de 93 Ko, alors que l'image 320 px n'a qu'une taille de 39 Ko.

Décision de nature artistique

Pour résumer, le problème des décisions de nature artistique réside dans le choix des modifications à apporter à l'image selon les diverses tailles d'affichage. Par exemple, si un instantané d'un grand plan paysager avec une personne au milieu, correctement affiché sur un site Web avec le navigateur d'un ordinateur de bureau, est rétréci lorsque ce même site est visionné sur un navigateur de mobile, cet instantané risque d'avoir mauvaise mine, car la personne sera vraiment minuscule et difficile à voir. Il serait probablement préférable de montrer sur un mobile une image portrait plus petite d'un zoom sur la personne. L'élément <picture> nous permet d'implémenter ce type de solution.

Revenons à notre exemple initial du fichier not-responsive.html. Cette image nécessite d'opérer un choix de nature artistique :

<img src="elva-800w.jpg" alt="Chris debout tenant sa fille Elva dans ses bras">

Arrangeons cela avec <picture>} ! Comme pour <vidéo> et <audio>, l'élément <picture> est une enveloppe conteneur de plusieurs éléments <source>} ; ces éléments indiquent plusieurs sources différentes entre lesquelles le navigateur peut choisir ; ils sont suivis du très important élément <img>}. Le code dans responsive.html ressemblera à :

<picture>
  <source media="(max-width: 799px)" srcset="elva-480w-close-portrait.jpg">
  <source media="(min-width: 800px)" srcset="elva-800w.jpg">
  <img src="elva-800w.jpg" alt="Chris debout tenant sa fille Elva dans ses bras">
</picture>
  • Les éléments <source> incluent un attribut media qui contient une condition pour le média — comme avec le premier exemple srcset, ces conditions sont testées pour décider de l'image à montrer — le premier qui renvoie true sera affiché. Dans notre cas, si la largeur de la fenêtre est de 799 px ou moins, l'image du premier élément <source> sera affichée. Si la largeur de la fenêtre est de 800 px plus, ce sera la deuxième.
  • Les attributs srcset contiennent le chemin vers l'image à afficher. Noter que comme avec <img> plus haut, <source> peut prendre plusieurs attributs srcset référençant plusieurs images, ainsi qu'un attribut sizes également.  Ainsi, non seulement vous pouvez offrir plusieurs images par l'intermédiaire d'un élement <picture> element, mais aussi offrir plusieurs résolutions pour chacune d'entre elles. En réalité, vous ne ferez pas ce type de montage très souvent.
  • Dans tous les case, vous devez fournir un élément <img>, avec src et  alt, juste avant </picture>, sinon aucune image n'apparaîtra. Cet élément ménage un cas par défaut appliqué si aucune des conditions de média ne renvoie vrai (vous pouvez réellement enlever le deuxième élément <source> dans cet exemple), et un repli pour les navigateurs qui ne prennent pas en charge l'élément <picture>.

Ce code nous permet d'afficher une image adaptée à la fois sur un écran large et sur un écran étroit, comme montré ci‑dessous :

Our example site as viewed on a wide screen - here the first image works ok, as it is big enough to see the detail in the center.Our example site as viewed on a narrow screen with the picture element used to switch the first image to a portrait close up of the detail, making it a lot more useful on a narrow screen

Note : Vous ne devez utiliser l'attribut media qu'avec un scénario de décision de nature artistique ; quand vous utilisez media, ne mettez pas de conditions pour le média avec l'attribut sizes.

Pourquoi ne peut-on pas réaliser cela avec le CSS ou du JavaScript ?

Lorsque le navigateur commence à charger une page, il commence à télécharger (précharger) toutes les images avant que l'analyseur principal n'ait commencé à charger et à interpréter le CSS et le JavaScript de la page. Cette technique est utile car elle permet de réduire de 20 % en moyenne le temps de chargement des pages. Cependant, elle n'est d'aucune aide pour les images adaptatives, d'où la nécessité de mettre en œuvre des solutions comme srcset. Vous ne pourriez pas, par exemple, charger l'élément <img>}, puis détecter la largeur de fenêtre avec JavaScript et changer dynamiquement l'image source pour une image plus petite si désiré. A ce moment-là, l'image originale aurait déjà été chargée, et vous chargeriez en plus la petite image, ce qui est encore pire en termes d'image adaptative.

Utilisez largement les formats d'image modernes

Il existe plusieurs nouveaux formats d'image très interessants (comme WebP et JPEG-2000) qui sont à la fois de taille réduite et de haute qualité. Toutefois, la prise en charge par les navigateurs est ponctuelle.

<picture> nous permet de servir encore les plus vieux explorateurs. Vous pouvez indiquer le type MIME dans les attributs type de façon à ce que l'explorateur puisse immédiatement rejeter les types de fichiers non pris en charge :

<picture>
  <source type="image/svg+xml" srcset="pyramid.svg">
  <source type="image/webp" srcset="pyramid.webp"> 
  <img src="pyramid.png" alt="Pyramide régulière constituée de quatre triangles équilatéraux">
</picture>
  • N'utilisez pas l'attribut media, sauf à devoir prendre une décision de nature artistique.
  • Dans un élément <source>, vous ne pouvez vous référer qu'à des images du type déclaré avec type.
  • Comme précédemment, il n'y a pas d'inconvénient à utiliser des listes avec une virgule comme séparateur avec srcset et sizes, selon les besoins.

Apprentissage actif : mise en œuvre de vos images adaptatives

Pour cet apprentissage actif, nous attendons que vous soyiez courageux et que vous y alliez seul.... la plupart du temps. Nous souhaitons que vous preniez une décision artistique en mettant en place vos  propres écrans étroit et large en utilisant <image>, et un exemple de commutation de résolution en utilisant srcset.

  1. Écrivez un HTML simple contenant votre code (utilisez not-responsive.html comme point de départ si vous voulez)
  2. Trouvez une jolie image de paysage de grande largeur avec quelques détails à l'intérieur. Créez une version taille web de cette dernière avec un éditeur graphique, puis découpez en une partie plus petite qui zoome sur un des détails, et créez une deuxième image (une largeur de l'ordre de 480 px conviendra parfaitement).
  3. Utilisez l'élément <picture> pour implémenter une bascule d'image en décision artistique !
  4. Créez plusieurs fichiers image de tailles différentes, chacun montrant la même image.
  5. Utilisez srcset/size pour créer un exemple de commutateur de résolution, soit pour servir une image de même taille avec différentes résolutions, ou diverses tailles d'images avec diverses largeur de vue.

Note : Utilisez les outils de développement du navigateur pour vous aider dans le choix des tailles dont vous avez besoin, comme mentionné plus haut.

Résumé

Voilà notre paquet‑cadeau pour des images adaptatives — nous espérons que ces nouvelles techniques vous plaisent. Résumons, nous vous avons exposé deux méthodes distinctes pour résoudre ce problème :

  • les décisions de nature artistique : cette méthode consiste à servir des images recadrées selon les diverses mises en page — par exemple, une image paysagère offrant toute la scène pour une mise en page destinée aux ordinateurs de bureau et une image portrait montrant le sujet principal zoomé de près pour une mise en page destinée aux mobiles. On resout alors ce problème avec <picture>.
  • la commutation de résolution : cette méthode consiste à servir des images issues de fichiers plus petits pour les périphériques à petit écran, car ils n'ont que faire des grosses images prévues pour les écrans d'ordinateurs de bureau — et en plus, en option, adapter la résolution de l'image aux écrans de faible ou grande densité. On resout ce problème avec l'utilisation de graphiques vectoriels (images SVG) ainsi qu'à l'aide des attributs srcset et sizes.

Cet article est aussi la conclusion de l'ensemble du module Multimedia et intégration ! Avant de passer à autre chose, il vous reste à essayer notre évaluation multimédia et à voir comment vous vous en sortez. Amusez-vous bien.

Voir aussi

Étiquettes et contributeurs liés au document

Contributeurs à cette page : Dralyab, edspeedy, SphinxKnight
Dernière mise à jour par : Dralyab,