--- title: Images adaptatives slug: Learn/HTML/Multimedia_and_embedding/Responsive_images tags: - Design - Débutant - Graphics - Guide - HTML - Image - Intermediate - Intermédiaire - img - picture - sizes - srcset translation_of: Learn/HTML/Multimedia_and_embedding/Responsive_images original_slug: Apprendre/HTML/Comment/Ajouter_des_images_adaptatives_à_une_page_web ---
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 {{htmlattrxref("srcset", "img")}} et l'élément {{htmlelement("picture")}} pour implémenter des solutions d'images adaptatives sur les sites Web. |
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 :
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 :
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 !
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éfinie 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 — {{htmlattrxref("srcset", "img")}}/{{htmlattrxref("sizes", "img")}}/{{htmlelement("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.)
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 {{htmlelement("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.
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 {{htmlelement("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 — {{htmlattrxref("srcset", "img")}} et {{htmlattrxref("sizes", "img")}} — 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 :
elva-fairy-480w.jpg
),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
(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 »,440px
).Note : Pour définir une largeur d'emplacement, vous pouvez indiquer une taille absolue (px
, em
) ou relative au viewport (vw), mais pas en 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 :
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 {{htmlattrxref("src", "img")}}.
Note : Dans l'élément {{htmlelement("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.)
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 {{htmlelement("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.
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.
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">
Dans 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.
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 {{htmlelement("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 {{htmlelement("picture")}}} ! Comme pour <vidéo>
et <audio>
, l'élément <picture>
est une enveloppe conteneur de plusieurs éléments {{htmlelement("source")}}} ; ces éléments indiquent plusieurs sources différentes entre lesquelles le navigateur peut choisir ; ils sont suivis du très important élément {{htmlelement("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>
<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.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.<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 :
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.
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 {{htmlelement("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.
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>
media
, sauf à devoir prendre une décision de nature artistique.<source>
, vous ne pouvez vous référer qu'à des images du type déclaré avec type
.srcset
et sizes
, selon les besoins.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.
not-responsive.html
comme point de départ si vous voulez)<picture>
pour implémenter une bascule d'image en décision artistique !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.
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 :
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.