6 octobre 2018 La petite clinique des images responsives Passer de ! à " en 1h30
A presentation at Paris Web in October 2018 in Paris, France by Nicolas Hoizey
6 octobre 2018 La petite clinique des images responsives Passer de ! à " en 1h30
Nicolas Hoizey Co-fondateur, directeur de l’innovation @nhoizey @nhoizey@cafe.des-blogueurs.org
Bref rappel
Un standard => plusieurs usages • • Le standard « Picture » porte plutôt mal son nom • • Mais aussi des attributs srcset et sizes utilisables directement sur <img> Il apporte bien une nouvelle balise <picture> (et <source> déjà connue avec <video>/<audio>) Ce qui nous permet de gérer différents cas… 4
srcset-x Beau Soleil Bannière Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Beau Soleil Menu Menu Menu Beau Soleil Menu Menu Menu Menu Menu Menu Menu Bannière Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Bannière Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit Lorem ipsum dolor sit Lorem ipsum dolor sit Largeur d’image fixe et densité d’écran variable <img src="…" alt="…" srcset="image.jpg 1x, image-2x.jpg 2x"> 5
srcset-w Beau Soleil Bannière Beau Soleil Menu Menu Menu Beau Soleil Menu Menu Menu Menu Menu Menu Menu Bannière Bannière Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. Largeur d’image variable, pleine largeur, et densité d’écran variable <img src="…" alt="…" srcset="image-640.jpg 640w, image-1024.jpg 1024w"> 6
srcset-w et sizes Beau Soleil Bannière Beau Soleil Menu Menu Menu Beau Soleil Menu Menu Menu Menu Menu Menu Menu Bannière Lorem ipsum dolor sit amet, consectet adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. Bannière Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Largeur d’image variable, différente selon breakpoints, et densité d’écran variable <img src="…" alt="…" srcset="image-640.jpg 640w, image-1024.jpg 1024w" sizes="(max-width: 640px) 100vw, (max-width: 1280px) 60vw, 400px"> 7
picture, source, srcset-w et sizes Beau Soleil Bannière Lorem ipsum dolor Beau Soleil Menu Menu Menu Beau Soleil Menu Menu Menu Menu Menu Menu Menu Bannière Lorem ipsum dolor Lorem ipsum dolor sit amet, consectetur Bannière Lorem ipsum dolor Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis odio dui, varius ac enim quis, accumsan porta nulla. Sed laoreet nibh sit amet lobortis porta. Donec sagittis est a tortor varius consectetur. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis odio dui, varius ac enim quis, accumsan porta nulla. Sed laoreet nibh sit amet lobortis porta. Donec sagittis est a tortor varius consectetur. Praesent sit amet sollicitudin mauris, non bibendum ante. Integer imperdiet in magna ac elementum. Sed arcu nibh, mattis ac tortor ultricies, consequat varius odio. Morbi at nunc at dolor auctor imperdiet in sit amet tortor. Largeur d’image variable, contenu ou ratio different selon breakpoints, et densité d’écran variable <picture> <source media=”(max-width: 1280px)" srcset="…" sizes="100vw"> <img src="…" alt="…" srcset="…" sizes="500px"> </picture> 8
Vos questions
Un dépôt Github https://github.com/nhoizey/pw2018-responsive-images
!
Beau Soleil Bannière Beau Soleil Menu Menu Menu Beau Soleil Menu Menu Menu Menu Menu Menu Menu Bannière Lorem ipsum dolor sit amet, consectet adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. Bannière Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. <img src="…" alt="…" ordre indifferent srcset="image-640.jpg 640w, image-1024.jpg 1024w" sizes="(max-width: 640px) 100vw, (max-width: 1280px) 60vw, 400px"> ordre primordial 14
Beau Soleil Bannière Lorem ipsum dolor Beau Soleil Menu Menu Menu Beau Soleil Menu Menu Menu Menu Menu Menu Menu Bannière Lorem ipsum dolor Lorem ipsum dolor sit amet, consectetur Bannière Lorem ipsum dolor Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis odio dui, varius ac enim quis, accumsan porta nulla. Sed laoreet nibh sit amet lobortis porta. Donec sagittis est a tortor varius consectetur. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis odio dui, varius ac enim quis, accumsan porta nulla. Sed laoreet nibh sit amet lobortis porta. Donec sagittis est a tortor varius consectetur. Praesent sit amet sollicitudin mauris, non bibendum ante. Integer imperdiet in magna ac elementum. Sed arcu nibh, mattis ac tortor ultricies, consequat varius odio. Morbi at nunc at dolor auctor imperdiet in sit amet tortor. <picture> <source media="(max-width: 1280px)" srcset="…" sizes="100vw"> <img src="…" alt="…" srcset="…" sizes="500px"> </picture> ordre primordial 15
<picture> <source type="image/webp" srcset="./image.webp"> <img src="./image.jpg" alt="…"> </picture>
!
Beau Soleil Bannière Beau Soleil Menu Menu Menu Beau Soleil Menu Menu Menu Menu Menu Menu Menu Bannière Lorem ipsum dolor sit amet, consectet adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. @media (min-width: 640px) { .card img { width: 60vw; } } @media (min-width: 1280px) { .card img { width: 400px; } } Bannière Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. 21
Beau Soleil Bannière Beau Soleil Menu Menu Menu Beau Soleil Menu Menu Menu Menu Menu Menu Menu Bannière Lorem ipsum dolor sit amet, consectet adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. @media (min-width: 640px) { .card img { width: 60vw; } } Lorem ipsum dolor sit amet, consectet adipiscing elit. Bannière Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. <img src="…" alt="…" srcset="image-640.jpg 640w, image-1024.jpg 1024w" sizes="(max-width: 640px) 100vw, (max-width: 1280px) 60vw, 400px"> 22
Beau Soleil Bannière Beau Soleil Menu Menu Menu Beau Soleil Menu Menu Menu Menu Menu Menu Menu Bannière Lorem ipsum dolor sit amet, consectet adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. @media (min-width: 640px) { .card img { width: 60vw; } } Lorem ipsum dolor sit amet, consectet adipiscing elit. Bannière Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. <img src="…" alt="…" srcset="image-640.jpg 640w, image-1024.jpg 1024w" sizes="(max-width: 640px) 100vw, (max-width: 1280px) 60vw, 400px"> 23
Beau Soleil Bannière Beau Soleil Menu Menu Menu Beau Soleil Menu Menu Menu Menu Menu Menu Menu Bannière Lorem ipsum dolor sit amet, consectet adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. @media (min-width: 640px) { .card img { width: 60vw; } } Lorem ipsum dolor sit amet, consectet adipiscing elit. Bannière Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. <img src="…" alt="…" srcset="image-640.jpg 640w, image-1024.jpg 1024w" sizes="(max-width: 639px) 100vw, (max-width: 1279px) 60vw, 400px"> 24
Beau Soleil Bannière Beau Soleil Menu Menu Menu Beau Soleil Menu Menu Menu Menu Menu Menu Menu Bannière Lorem ipsum dolor sit amet, consectet adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. @media (min-width: 640px) { .card img { width: 60vw; } } Lorem ipsum dolor sit amet, consectet adipiscing elit. Bannière Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. <img src="…" alt="…" srcset="image-640.jpg 640w, image-1024.jpg 1024w" sizes="(min-width: 1280px) 400px, (min-width: 640px) 60vw, 100vw"> 25
Des em ? https://talks.nicolas-hoizey.com/HDbr1q/un-petit-pas-pour-l-em-un-grand-pas-pour-le-web
Beau Soleil Bannière Beau Soleil Menu Menu Menu Beau Soleil Menu Menu Menu Menu Menu Menu Menu Bannière Lorem ipsum dolor sit amet, consectet adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. @media (min-width: 40em) { .card img { width: 60vw; } } Lorem ipsum dolor sit amet, consectet adipiscing elit. Bannière Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. <img src="…" alt="…" srcset="image-640.jpg 640w, image-1024.jpg 1024w" sizes="(min-width: 80em) 400px, (min-width: 40em) 60vw, 100vw"> 27
Beau Soleil Bannière Beau Soleil Menu Menu Menu Beau Soleil Menu Menu Menu Menu Menu Menu Menu Bannière Lorem ipsum dolor sit amet, consectet adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectet adipiscing elit. @media (min-width: 40em) { .card img { width: 60vw; } } Lorem ipsum dolor sit amet, consectet adipiscing elit. Bannière Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. <img src="…" alt="…" srcset="image-640.jpg 640w, image-1024.jpg 1024w" sizes="(min-width: 80em) 400px, (min-width: 40em) 60vw, 100vw"> 28
Analyse détaillée d’un cas concret
Le besoin exprimé Comment écrire que pour un écran + grand je veux une image plus petite et vice versa ? ● format "large" (>= 1024px), 2 colonnes (en 50/50) dont l'une comprend une image qui occupe 100% de sa colonne. Cette colonne est flexible et sa largeur max est de 740px (donc image max width = 740px) ● format "réduit" (<1024px), une seule colonne, l'image occupe 100% de la largeur disponible. donc image max width = 1023px.
Interprétations de l’énoncé On a supposé que les images sont fluides, les dimensions indiquées sur les wireframe correspondants à certains cas précis.
Une solution proposée <picture> <source media="(max-width:29.9375rem)" srcset="./img-440x220.jpg"> <source media="(max-width:47.9375rem)" srcset="./img-750x375.jpg"> <source media="(max-width:63.9375rem)" srcset="./img-1023x900.jpg"> <source media="(min-width:64rem)" srcset="./img-740x900.jpg"> <img src="./img-900x900.jpg" alt="" /> </picture>
Analyse… <picture> <source media="(max-width:29.9375rem)" srcset="./img-440x220.jpg"> <source media="(max-width:47.9375rem)" srcset="./img-750x375.jpg"> <source media="(max-width:63.9375rem)" srcset="./img-1023x900.jpg"> <source media="(min-width:64rem)" srcset="./img-740x900.jpg"> <img src="./img-900x900.jpg" alt="" /> </picture> Les media queries des 4 <source> couvrent tous les viewports. Ce n’est pas une erreur, mais c’est inutile, le dernier srcset peut aller dans le <img>. (Évite aussi une potentielle surprise si le viewport se retrouve — très peu probable certes — entre 63.9375rem et 64rem.)
<picture> <source media="(max-width:29.9375rem)" srcset="./img-440x220.jpg"> <source media="(max-width:47.9375rem)" srcset="./img-750x375.jpg"> <source media="(max-width:63.9375rem)" srcset="./img-1023x900.jpg"> <img src="./img-900x900.jpg" srcset="./img-740x900.jpg" alt="" /> </picture>
<picture> <source media="(max-width:29.9375rem)" srcset="./img-440x220.jpg"> <source media="(max-width:47.9375rem)" srcset="./img-750x375.jpg"> <source media="(max-width:63.9375rem)" srcset="./img-1023x900.jpg"> <img src="./img-900x900.jpg" srcset="./img-740x900.jpg" alt="" /> </picture> Juste avant 30rem (~480px), l’image chargée fait 440px, alors qu’il faudrait 480px pour les écrans de densité 1. Sur les petits viewports, les densités sont le plus souvent >= 2, donc il faudrait fournir au moins une image x2. On traitera ces sujets plus tard.
<picture> <source media="(max-width:29.9375rem)" srcset="./img-440x220.jpg"> <source media="(max-width:47.9375rem)" srcset="./img-750x375.jpg"> <source media="(max-width:63.9375rem)" srcset="./img-1023x900.jpg"> <img src="./img-900x900.jpg" srcset="./img-740x900.jpg" alt="" /> </picture> Les deux premières sources chargent une image de même ratio 2/1 et de même contenu visuel. Ce sont des max-width, la seconde suffit. On peut lui donner les deux tailles d’image, par contre, pour que les petits viewports ne chargent pas la grande.
<picture> <source media="(max-width:47.9375rem)" srcset="./img-440x220.jpg, ./img-750x375.jpg"> <source media="(max-width:63.9375rem)" srcset="./img-1023x900.jpg"> <img src="./img-900x900.jpg" srcset="./img-740x900.jpg" alt="" /> </picture> Attention, on perd une caractéristique du code précédent, on y reviendra.
<picture> <source media="(max-width:47.9375rem)" srcset="./img-440x220.jpg ???, ./img-750x375.jpg ???"> <source media="(max-width:63.9375rem)" srcset="./img-1023x900.jpg 1x"> <img src="./img-900x900.jpg" srcset="./img-740x900.jpg 1x" alt="" /> </picture> Soucis : il manque les descripteurs sur les images dans les srcset : x ou w ? Une seule image dans le srcset -> interprété comme un 1x La première source (de 0rem à ~48rem) a pour objectif de montrer une image de largeur variable, c’est un descripteur w qu’il faut utiliser.
<picture> <source media="(max-width:47.9375rem)" srcset="./img-440x220.jpg 440w, ./img-750x375.jpg 750w"> <source media="(max-width:63.9375rem)" srcset="./img-1023x900.jpg 1023w"> <img src="./img-900x900.jpg" srcset="./img-740x900.jpg 740w" alt="" /> </picture>
<picture> <source media="(max-width:47.9375rem)" srcset="./img-440x220.jpg 440w, ./img-750x375.jpg 750w"> <source media="(max-width:63.9375rem)" srcset="./img-1023x900.jpg 1023w"> <img src="./img-900x900.jpg" srcset="./img-740x900.jpg 740w" alt="" /> </picture> En fusionnant les deux premières <source>, on a perdu la limitation de largeur d’image à 440px pour les viewports < 30rem. En l’absence d’attribut sizes, sa valeur par défaut est 100vw. (L’attribut sizes est obligatoire selon la spec HTML du WHATWG, mais toujours pas dans la version 5.2 du W3C…) Avec un viewport de 30rem (~480px) : ● L’image 440x220 sera chargée sur un écran de densité < ~1.5, comme initialement ● L’image 750x375 sera chargée sur un écran de densité > ~1.5 (750/480), au lieu de 440x220 Dans le principe général des images responsives, on n’a en fait rien perdu, mais plutôt gagné en qualité visuelle sur les petits viewports avec écrans haute densité. Mais ne pas servir une image plus grande pour les hautes densités peut être un choix légitime. À arbitrer.
<picture> <source media="(max-width:47.9375rem)" srcset="./img-440x220.jpg 440w, ./img-750x375.jpg 750w"> <source media="(max-width:63.9375rem)" srcset="./img-1023x900.jpg 1023w"> <img src="./img-900x900.jpg" srcset="./img-740x900.jpg 740w" alt="" /> </picture> Dans le besoin exprimé, l’image est de même ratio pour tous les viewports < 1024px (~64rem). On peut fusionner les deux premières <source> et changer la hauteur de la troisième image.
<picture> <source media="(max-width:63.9375rem)" srcset="./img-440x220.jpg 440w, ./img-750x375.jpg 750w, ./img-1024x512.jpg 1024w"> <img src="./img-900x900.jpg" srcset="./img-740x900.jpg 740w" alt="" /> </picture>
<picture> <source media="(max-width:63.9375rem)" srcset="./img-440x220.jpg 440w, ./img-750x375.jpg 750w, ./img-1024x512.jpg 1024w"> <img src="./img-900x900.jpg" srcset="./img-740x900.jpg 740w" sizes="???" alt="" /> </picture> Sur petits écrans, la valeur par défaut sizes="100vw" convient. Mais ce n’est pas le cas sur plus grands écrans (>= 64rem =~ 1024px) où l’image doit occuper la demi largeur uniquement, avec une limite à 740px. Le fallback dans src pourrait d’ailleurs être limité aussi à 740px. Il n’y a qu’une image dans srcset, donc pas de risque de télécharger la « mauvaise » image trop grande dans l’absolu, mais le navigateur « pense » avoir besoin d’une image pleine largeur. On devrait pouvoir : ● Fournir une image moins large sur écrans de densité 1 et viewport < 1480px ● Fournir une image plus large sur écrans de densité supérieure
<picture> <source media="(max-width:63.9375rem)" srcset="./img-440x220.jpg 440w, ./img-750x375.jpg 750w, ./img-1024x512.jpg 1024w" sizes="100vw"> <img src="./img-740x900.jpg" srcset="./img-512x623.jpg 512w, ./img-740x900.jpg 740w, ./img-1480x1800.jpg 1480w" sizes="(min-width: 92rem) 740px, (min-width: 64rem) 50vw, 100vw" alt="" /> </picture>
Code optimisé <picture> <source media="(max-width:63.9375rem)" srcset="./img-440x220.jpg 440w, ./img-750x375.jpg 750w, ./img-1024x512.jpg 1024w" sizes="100vw"> <img src="./img-740x900.jpg" srcset="./img-512x623.jpg 512w, ./img-740x900.jpg 740w, ./img-1480x1800.jpg 1480w" sizes="(min-width: 92rem) 740px, (min-width: 64rem) 50vw, 100vw" alt="" /> </picture>
Amélioration potentielle supplémentaire Inverser les sources pour avoir media="(min-width: 64rem)" et éviter les risques de « trou » : <picture> <source media="(min-width:64rem)" srcset="./img-512x623.jpg 512w, ./img-740x900.jpg 740w, ./img-1480x1800.jpg 1480w" sizes="(min-width: 92rem) 740px, (min-width: 64rem) 50vw, 100vw" <img src="./img-740x900.jpg" srcset="./img-440x220.jpg 440w, ./img-750x375.jpg 750w, ./img-1024x512.jpg 1024w" sizes="100vw"> alt="" /> </picture>
Mais en fait…
Le « vrai » besoin Le besoin réellement exprimé par le client est que l’image ne soit pas fluide, mais fasse toujours 900px de hauteur, quelle que soit la largeur de viewport, avec un crop latéral. Constats : • • Ce n’est pas le comportement fluide « naturel » des images dans la plupart des sites ○ Sur un écran 320x480, l’image fera plus de deux écrans de hauteur… On ne pourra pas éviter de charger des images plus grandes que nécessaires sur une grande partie des viewports
Solution minimaliste ● Une <source> ● Des descripteurs x pour gérer les variations de densité, puisqu’on n’a pas de variation ● de largeur object-fit: cover; pour opérer le crop en CSS
Solution minimaliste <picture> <source media="(min-width:64rem)" srcset="./img-740x900.jpg 1x, ./img/1480x1800.jpg 2x"> <img src="./img-740x900.jpg" srcset="./img-1023x900.jpg 1x, ./img-2046x900.jpg 2x" alt="" /> </picture>
Solution optimisée • • • Plusieurs <source> pour limiter le surplus de pixels croppés On fixe ici des paliers arbitraires à 40rem, 75rem et 85rem Il faudrait analyser les viewports les plus courants des visiteurs pour fixer des paliers optimaux
Viewport < 64rem Viewport >= 64rem Solution optimisée <picture> <source media="(min-width:85rem)" srcset="./img-740x900.jpg 1x, ./img-1480x1800.jpg 2x"> <source media="(min-width:75rem)" srcset="./img-680x900.jpg 1x, ./img-1360x1800.jpg 2x"> <source media="(min-width:64rem)" srcset="./img-600x900.jpg 1x, ./img-1200x1800.jpg 2x"> <source media="(min-width:40rem)" srcset="./img-1024x900.jpg 1x, ./img-2048x1800.jpg 2x"> <img src="./img-740x900.jpg" srcset="./img-640x900.jpg 1x, ./img-1280x900.jpg 2x" alt="" /> </picture> L’image se fige à 740px (92.5rem), taille nécessaire aussi sur la tranche inférieure, fixée à 85rem. Donc pas besoin de <source> avec media query à 92.5rem. La largeur d’image nécessaire est fixée par rapport au palier supérieur : 75rem * 16px / 2 = 600px
D’autres questions ?
À la semaine prochaine ? Mardi 9 octobre 2018 à Bordeaux L’événement français des mordus de web performance ! https://www.welovespeed.com/ <img src="…" alt="…” srcset="image-???.jpg ???w, image-???.jpg ???w, image-???.jpg ???w"> Comment choisir les dimensions optimale pour le srcset ?
À vous de jouer ! illustrations : @nhoizey @nhoizey@cafe.des-blogueurs.org