Syntaxes prescriptives

L'élément <picture> n'affiche rien de lui-même, mais sert de moteur de décision pour un élément <img> interne, en lui indiquant ce qu'il faut afficher. <picture> suit un précédent déjà défini par les éléments <audio> et <video>: un élément wrapper contenant des éléments <source> individuels.

<picture>
   <source …>
   <source …>
    <img …>
</picture …>

Cette <img> interne vous fournit également un modèle de remplacement fiable pour les navigateurs plus anciens qui ne sont pas compatibles avec les images responsives : si l'élément <picture> n'est pas reconnu par le navigateur de l'utilisateur, il est ignoré. Les éléments <source> sont également supprimés, car le navigateur ne les reconnaîtra pas du tout, ou n'aura pas de contexte pertinent pour eux sans un parent <video> ou <audio>. Toutefois, l'élément <img> interne sera reconnu par n'importe quel navigateur, et la source spécifiée dans son src sera affichée comme prévu.

Images "directes artistiques" avec <picture>

La modification du contenu ou du format d'une image en fonction de sa taille est généralement désignée par le terme d'images responsives "directes artistiques". srcset et sizes sont conçus pour fonctionner de manière invisible et en échangeant facilement les sources selon les indications du navigateur de l'utilisateur. Cependant, vous aurez parfois besoin de modifier les sources au niveau des points d'arrêt pour mieux mettre en évidence le contenu, de la même manière que vous adaptez la mise en page. Par exemple, une image d'en-tête pleine largeur avec un petit point central peut convenir à une grande fenêtre d'affichage :

Image de largeur d&#39;en-tête d&#39;une fleur de pervenche entourée de feuilles et de tiges, vue par une abeille.

Toutefois, lorsqu'elle est réduite pour s'adapter aux fenêtres d'affichage de petite taille, il est possible que le centre de l'image ne soit plus au centre:

Image de largeur d&#39;en-tête d&#39;une fleur de pervenche, réduite. L&#39;abeille est à peine visible.

Le sujet de ces sources d'images est le même, mais afin de mieux vous concentrer sur ce sujet visuellement, vous devez modifier les proportions de la source de l'image entre les points d'arrêt. Par exemple, un zoom plus serré sur le centre de l'image et une partie des détails au niveau des bords sont recadrées:

Recadrage rapproché de la fleur de pervenche.

Ce type de "recadrage" peut être réalisé via CSS, mais l'utilisateur demande toutes les données qui composent cette image, même s'il ne la voit peut-être jamais.

Chaque élément source comporte des attributs définissant les conditions de sélection de ce source: media, qui accepte une requête média, et type, qui accepte un type de contenu (anciennement "type MIME"). Le premier <source> de l'ordre source correspondant au contexte de navigation actuel de l'utilisateur est sélectionné. Le contenu de l'attribut srcset de cette source est utilisé pour déterminer les candidats appropriés pour ce contexte. Dans cet exemple, le premier source avec un attribut media correspondant à la taille de la fenêtre d'affichage de l'utilisateur sera celui sélectionné:

<picture>
  <source media="(min-width: 1200px)" srcset="wide-crop.jpg">
  <img src="close-crop.jpg" alt="…">
</picture>

Vous devez toujours spécifier la img interne en dernier dans l'ordre. Si aucun des éléments source ne correspond à leurs critères media ou type, l'image fera office de source par défaut. Si vous utilisez des requêtes média min-width, il est préférable de commencer par les sources les plus importantes, comme illustré dans le code précédent. Lorsque vous utilisez des requêtes média max-width, placez la plus petite source en premier.

<picture>
   <source media="(max-width: 400px)" srcset="mid-bp.jpg">
   <source media="(max-width: 800px)" srcset="high-bp.jpg">
   <img src="highest-bp.jpg" alt="…">
</picture>

Lorsqu'une source est choisie en fonction des critères que vous avez spécifiés, l'attribut srcset de source est transmis à <img> comme s'il était défini sur <img> lui-même. Cela signifie que vous êtes libre d'utiliser sizes pour optimiser également les sources d'images orientées illustration.

<picture>
   <source media="(min-width: 800px)" srcset="high-bp-1600.jpg 1600w, high-bp-1000.jpg 1000w">
   <source srcset="lower-bp-1200.jpg 1200w, lower-bp-800.jpg 800w">
   <img src="fallback.jpg" alt="…" sizes="calc(100vw - 2em)">
</picture>

Bien entendu, une image dont les proportions peuvent varier en fonction de l'élément <source> sélectionné pose un problème de performances : <img> n'accepte qu'un seul attribut width et height, mais omettre ces attributs peut nuire à l'expérience utilisateur. Pour tenir compte de cela, un ajout relativement récent (mais bien compatible) à la spécification HTML permet d'utiliser les attributs height et width sur les éléments <source>. Ils permettent de réduire les décalages de mise en page tout aussi bien que dans <img>, avec l'espace approprié réservé dans votre mise en page, quel que soit l'élément <source> sélectionné.

<picture>
   <source
      media="(min-width: 800px)"
      srcset="high-bp-1600.jpg 1600w, high-bp-1000.jpg 1000w"
      width="1600"
      height="800">
   <img src="fallback.jpg"
      srcset="lower-bp-1200.jpg 1200w, lower-bp-800.jpg 800w"
      sizes="calc(100vw - 2em)"
      width="1200"
      height="750"
      alt="…">
</picture>

Il est important de noter que la direction artistique ne peut pas servir que pour des décisions basées sur la taille de la fenêtre d'affichage. Cela devrait être le cas, étant donné que la plupart de ces cas peuvent être traités plus efficacement avec srcset/sizes. Par exemple, la sélection d'une source d'image mieux adaptée au jeu de couleurs dicté par les préférences de l'utilisateur:

<picture>
   <source media="(prefers-color-scheme: dark)" srcset="hero-dark.jpg">
   <img srcset="hero-light.jpg">
</picture>

Attribut type

L'attribut type vous permet d'utiliser le moteur de décision de requête unique de l'élément <picture> pour ne diffuser que les formats d'image dans les navigateurs compatibles.

Comme vous l'avez appris dans la section Formats d'images et compression, un encodage que le navigateur ne peut pas analyser ne sera même pas reconnu en tant que données d'image.

Avant l'introduction de l'élément <picture>, les solutions d'interface les plus viables pour diffuser de nouveaux formats d'image exigeaient que le navigateur demande et tente d'analyser un fichier image avant de déterminer s'il devait le supprimer et charger une création de remplacement. Voici un exemple courant:

   <img src="image.webp"
    data-fallback="image.jpg"
    onerror="this.src=this.getAttribute('data-fallback'); this.onerror=null;"
    alt="...">

Avec ce modèle, une requête image.webp était quand même effectuée dans chaque navigateur, ce qui générait un transfert inutile pour les navigateurs non compatibles avec WebP. Les navigateurs qui ne pouvaient pas analyser l'encodage WebP génèrent un événement onerror et perdent la valeur data-fallback en src. C'était une solution inefficace, mais là encore, des approches comme celle-ci étaient la seule option disponible en interface. N'oubliez pas que le navigateur commence à envoyer des demandes d'images avant qu'un script personnalisé ne puisse s'exécuter, ou même être analysé, et que nous ne pouvons pas préempter ce processus.

L'élément <picture> est explicitement conçu pour éviter ces requêtes redondantes. Bien qu'il n'y ait toujours aucun moyen pour un navigateur de reconnaître un format non compatible sans le demander, l'attribut type avertit le navigateur à l'avance de l'encodage source, afin qu'il puisse décider ou non d'envoyer une requête.

Dans l'attribut type, vous indiquez le type de support (anciennement type MIME) de la source d'image spécifiée dans l'attribut srcset de chaque <source>. Le navigateur dispose ainsi de toutes les informations dont il a besoin pour déterminer immédiatement si l'image candidate fournie par ce source peut être décodée sans effectuer de requête externe. Si le type de média n'est pas reconnu, le <source> et tous ses candidats sont ignorés, et le navigateur poursuit.

<picture>
 <source type="image/webp" srcset="pic.webp">
 <img src="pic.jpg" alt="...">
</picture>

Ici, tout navigateur compatible avec l'encodage WebP reconnaît le type de média image/webp spécifié dans l'attribut type de l'élément <source>, sélectionne ce <source> et, comme nous n'avons fourni qu'un seul candidat dans srcset, indique au <img> interne de demander, transférer et afficher pic.webp. Tout navigateur non compatible avec WebP ignorera source et, sans instructions contraires, <img> affichera le contenu de src comme il le fait depuis 1992. Bien entendu, il n'est pas nécessaire de spécifier un deuxième élément <source> avec type="image/jpeg". Vous pouvez supposer que le format JPEG est compatible avec tous les formats.

Quel que soit le contexte de navigation de l'utilisateur, tout cela est réalisé via un seul transfert de fichier et aucune bande passante n'est gaspillée sur les sources d'image qui ne peuvent pas être affichées. Cette approche est tournée vers l'avenir: des formats de fichiers plus récents et plus efficaces seront fournis avec leurs propres types de support, et nous pourrons les exploiter grâce à picture, sans JavaScript, sans dépendances côté serveur et à la vitesse de <img>.

L'avenir des images responsives

Tous les modèles de balisage abordés ici représentaient une charge de travail importante en termes de standardisation: modifier la fonctionnalité d'un élément établi et central pour le Web en tant que <img> n'était pas une mince affaire, et la suite de problèmes que ces modifications visaient à résoudre étaient pour le moins considérables. Si vous vous êtes arrêté à penser que ces modèles de balisage peuvent être nettement améliorés, vous avez tout à fait raison. Dès le départ, ces normes visaient à fournir une base sur laquelle s'appuyer les futures technologies.

Toutes ces solutions dépendent nécessairement du balisage. Elles peuvent donc être incluses dans la charge utile initiale du serveur et arriver à temps pour que le navigateur demande des sources d'image. Une limitation qui rendait l'attribut sizes difficilement contrôlable.

Toutefois, depuis l'introduction de ces fonctionnalités sur la plate-forme Web, une méthode native de report des requêtes d'images a été introduite. Les éléments <img> avec l'attribut loading="lazy" ne sont pas demandés tant que la mise en page de la page n'est pas connue, afin de reporter les requêtes d'images en dehors de la fenêtre d'affichage initiale de l'utilisateur à une étape ultérieure du processus d'affichage de la page, ce qui peut potentiellement éviter les requêtes inutiles. Étant donné que le navigateur comprend parfaitement la mise en page au moment où ces requêtes sont envoyées, un attribut sizes="auto" a été proposé en tant qu'ajout de la spécification HTML pour éviter la contrainte des attributs sizes écrits manuellement dans ces cas.

Des ajouts à l'élément <picture> se profilent également à l'horizon, pour répondre à des changements particulièrement intéressants de la façon dont nous stylisons la mise en page. Bien que les informations de fenêtre d'affichage constituent une base solide pour les décisions de mise en page de haut niveau, elles nous empêchent d'adopter une approche du développement entièrement au niveau des composants, c'est-à-dire un composant qui peut être intégré à n'importe quelle partie d'une mise en page, avec des styles qui réagissent à l'espace occupé par le composant lui-même. Ce problème a entraîné la création de requêtes de conteneur, une méthode permettant d'appliquer un style aux éléments en fonction de la taille de leur conteneur parent, plutôt que de la seule fenêtre d'affichage.

Bien que la syntaxe de requête de conteneur ne soit que stabilisée et que la compatibilité avec les navigateurs soit très limitée au moment de la rédaction, l'ajout des technologies de navigateur qui l'activent fournira à l'élément <picture> un moyen de faire la même chose: un attribut container potentiel qui autorise des critères de sélection <source> basés sur l'espace occupé par <img>, plutôt que sur la taille de la fenêtre d'affichage.<picture>

Si cela vous semble un peu vague, ce n'est pas pour rien: ces discussions sur les normes Web sont en cours, mais loin d'être résolues, vous ne pouvez pas les utiliser pour le moment.

Bien que le balisage d'images responsif promet de simplifier l'utilisation au fil du temps, comme n'importe quelle technologie Web, il existe un certain nombre de services, de technologies et de frameworks permettant de faciliter l'écriture manuscrite de ce balisage. Dans le module suivant, nous verrons comment intégrer tout ce que nous avons appris sur les formats d'image, la compression et les images responsives dans un workflow de développement moderne.