Ajouter des images responsive à une page web

Dans cet article, apprenez comment utiliser HTML pour adapter les images de votre site pour différentes tailles d'écran ou différentes résolutions.

Prérequis : Vous devriez savoir comment créer un document HTML simple et comment ajouter des images statiques à une page web.
Objectifs : Apprendre comment fournir plusieurs fichiers sources pour l'élément <img> afin que le navigateur puisse utiliser la meilleure image dans chaque situation.

Note : Les images vectorielles sont les images adaptatives par excellence car les fichiers sont légers et les images sont redimensionnables pour n'importe quelle taille et sans perdre de résolution. Utilisez des images vectorielles dès que possible, elles seront encore plus efficaces que les techniques abordées dans cet article. Ici, nous illustrons comment utiliser plusieurs versions d'une image matricielles (bitmap), avec plusieurs tailles, pour fournoir le meilleur rendu selon la taille et la résolution de l'écran utilisée.

Cet article illustre comment mettre en place des images adaptatives avec HTML, dans certains cas, il est préférable d'utiliser CSS.

Pourquoi utiliser des images adaptatives ?

Voilà le problème qu'on cherche à résoudre :

Ce qu'on a sur une page web, c'est une zone qui doit être remplie par une image. Pour être plus précis, on a une zone qui doit être remplie par des pixels sur une largeur donnée et sur une hauteur donnée qui dépendent de l'appareil utilisé par le visiteur.

Vous disposez également d'un fichier, qui est une image, qui est un ensemble de pixels sur une certaine hauteur et une certaine largeur. L'image devrait donc trouver sa place dans une zone qui fait la même taille. Si la zone est trop grande, l'image n'aura pas assez de pixels et on aura l'impression qu'elle est pixellisée. En revanche, si la zone est trop petite, on gaspillera de la bande passante et on ralentira le chargement de la page car l'image sera plus grande que nécessaire.

Les images adaptatives permettent de résoudre ce problème en proposant plusieurs images au navigateur. Toutes ces images montrent la même chose mais contiennent une quantité de pixels différente. De cette façon, le navigateur pourra charger l'image la plus adapté, celle qui est suffisamment grande, sans qu'elle ralentisse la page pour autant.

Comment faire ?

Dans cette section, nous verrons comment résoudre le problème le plus courant : afficher le même contenu, avec une image dont la taille varie en fonction de l'appareil utilisé. Dans la section qui suit, nous verrons les solutions à mettre en œuvre pour quelques situations plus rares.

Vous souvenez-vous de l'élément <img> ? Il vous permet de diriger le navigateur vers un seul fichier source :

<img src="chalet.jpg" alt="Un chalet en bois dans les Alpes">

Nous allons utiliser deux nouveaux attributs : srcset et sizes sizes (en plus de alt et de src), afin de fournir plusieurs sources d'images et suffisamment d'indications pour que le navigateur puisse choisir celle qui sera la plus adapté. Cela ressemblera, au final, à :

<img
    src="chalet.jpg"
    alt="Un chalet en bois dans les Alpes"
    srcset="
        chalet-256.jpg 256w,
        chalet-512.jpg 512w,
        chalet-1024.jpg 1024w"
    sizes="
        (max-width: 500px) 100vw,
        (max-width: 900px) 40vw,
        400px">

srcset et sizes contiennent chacun des listes dont les éléments sont séparés par des virgules.

Pour srcset : entre chaque virgule, on écrira un élément composé :

  1. d'un nom de fichier d'image (chalet-256.jpg)
  2. d'un espace
  3. de la largeur inhérente à l'image, exprimées en pixels (256w)

Pour sizes : entre chaque virgule, on écrira un élément composé :

  1. d'une condition sur le média ((max-width:500px))
  2. d'un espace
  3. de la largeur de la zone à remplir par l'image quand la condition sur le média est vérifiée (100vw)
  • La largeur de la zone peut être exprimée en unités absolues (px, em) ou en unité relative (vw correspond au pourcentage de la largeur du viewport qui correspond à la taille de l'écran visible par l'utilisateur). Vous pouvez également utiliser une combinaison de telles quantités grâce à calc.
  • La dernière largeur de zone exprimée correspond à celle qui sera utilisée par défaut (quand aucune condition n'est vérifiée). La dernière largeur n'a donc aucune condition correspondante.
  • max-width signifie simplement « si l'écran de l'utilisateur n'est pas plus large que X pixels ».
  • Le navigateur ignorera les conditions suivantes dès qu'une condition sera vérifiée. Attention donc à l'ordre des conditions média.

Le navigateur ne pourrait-il pas consulter le CSS pour deviner la largeur de la zone de l'image ?

Non car le navigateur commence par précharger les ressources comme les images avant même de pouvoir interpréter le CSS et le JavaScript. Ce fonctionnement est utile car sinon, on aurait des images lourdes qui seraient chargées ou on ferait attendre le préchargement et la page prendrait plus de 20% de temps supplémentaire à charger.

Scénarios avancés

Des images de même taille mais de résolutions différentes

Si vous supportez différents affichages qui utilisent différentes densités de résolution mais qui ont la même taille (l'image aura donc une même surface), il vous faudra utiliser srcset avec des descripteurs de densité et sans l'attribut sizes :

<img
    src="chalet.jpg"
    alt="Un chalet en bois dans les Alpes"
    srcset="chalet.jpg,
        chalet-1-5x.jpg 1.5x,
        chalet-2x.jpg 2x,
        chalet-3x.jpg 3x">
  • 1x est implicite

  • x signifie que pour cet appareil, on a X pixels qui correspondent à 1 pixel CSS

Modification explicite de l'image

Afin que l'image soit la mieux adaptée, il peut arriver qu'on veuille

  1. La recadrer pour que le sujet de l'image soit plus facile à voir quand l'image est petite
  2. ou qu'on transforme une image prise en portrait afin de l'afficher au mieux dans une zone de type paysage (ou l'inverse)

Attention, l'image d'origine doit rester la même dans tous les cas, il ne s'agit pas de montrer une coccinelle à quelqu'un qui navigue sur un téléphone et une voiture à quelqu'un qui navigue depuis un ordinateur !

Ce problème est plus complexe et sa solution est donc également plus complexe : on utilisera l'élément <picture>. <picture> est un élément qui enveloppera plusieurs éléments <source>, suivis par le tout-puissant <img> :

<picture>
    <source
        media="(min-width: 1000px)"
        srcset="chalet-ordinateur.jpg">
    <source
        media="(min-width: 700px)"
        srcset="chalet-tablette.jpg">
    <img src="chalet-téléphone.jpg" alt="Un chalet dans les Alpes">
</picture>
  • De même qu'avec <img>, <source> accepte srcset et sizes. Dans le cas où on a des images adaptatives, il ne faut pas utiliser <source> et src ensemble.
  • <source> peut également contenir un attribut media qui contient une requête média (media query) CSS. Cet attribut media ne doit être utilisé que dans ce cas de modification explicite car il ne laisse aucun choix au navigateur pour l'image à utiliser. Lorsque vous utilisez media, il ne faut pas fournir de conditions média dans sizes.
  • Dans tous les cas, et avant </picture>, un élément <img> doit être fourni et il doit contenir des attributs src and alt, sinon, aucune image n'apparaîtra.

En avant les formats modernes

Plusieurs formats sont apparus (WebP et JPEG-2000 par exemple) qui permettent de maintenir une taille de fichier faible et une qualité d'image appréciable. Toutefois, ces formats ne sont pas supportés par tous les navigateurs, notamment les anciens.

<picture> permet de fournir d'autres formats à destination des anciens navigateurs. Pour ce faire, il faut utiliser l'attribut type pour fournir le type MIME afin que le navigateur puisse rejeter immédiatement les types de fichiers qu'il ne supporte pas :

<picture>
  <source type="image/svg+xml" srcset="pyramide.svg">
  <source type="image/webp" srcset="pyramide.webp"> 
  <img src="pyramide.png" alt="Une pyramide construite avec quatre triangles équilatéraux.">
</picture>
  • Ne pas utiliser l'attribut media sauf s'il est nécessaire d'appliquer une modification explicite à l'image
  • Dans l'élément <source>, il est impossible de faire référence à des images qui ne sont pas du type déclaré ave type.
  • Comme vu avant, on pourra utiliser des listes (avec la virgule comme séparateur) pour fournir différentes srcset et sizes si besoin

En savoir plus

Étiquettes et contributeurs liés au document

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