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é :
- d'un nom de fichier d'image (
chalet-256.jpg
) - d'un espace
- de la largeur inhérente à l'image, exprimées en pixels (
256w
)
Pour sizes
: entre chaque virgule, on écrira un élément composé :
- d'une condition sur le média (
(max-width:500px)
) - d'un espace
- 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
- La recadrer pour que le sujet de l'image soit plus facile à voir quand l'image est petite
- 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>
acceptesrcset
etsizes
. Dans le cas où on a des images adaptatives, il ne faut pas utiliser<source>
etsrc
ensemble. <source>
peut également contenir un attributmedia
qui contient une requête média (media query) CSS. Cet attributmedia
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 utilisezmedia
, il ne faut pas fournir de conditions média danssizes
.- Dans tous les cas, et avant
</picture>
, un élément<img>
doit être fourni et il doit contenir des attributssrc
andalt
, 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é avetype
. - Comme vu avant, on pourra utiliser des listes (avec la virgule comme séparateur) pour fournir différentes
srcset
etsizes
si besoin