Retina, ou la haute définition de manière plus générale pour les images de nos sites web pose un problème relatif. En effet depuis la sortie du premier Mac Book Pro à écran Retina (et avant pour certain), la question qui revient le plus souvent est : doit-on boycotter Retina, ou au contraire y accorder de l’importance ?

Je fais partie des gens indécis sur la question, et du coup cette position me va très bien pour écrire cet article, car j’en attends vos réactions.

Pour moi la HD, comme la 3D, fait partie de l’avenir de l’image, que ce soit au ciné, la télévision ou un écran d’ordinateur. C’est comme le son multicanal (plus connu sous le nom de son surround), aujourd’hui ça vous ferait bizarre d’aller au cinéma avec un son mono. Et bien pour la HD c’est pareil, dans quelques années nous ne pourrons plus nous en passer. C’est ce qui me fait dire qu’accorder un minimum d’importance à la HD sur le Web (ici Retina) n’est pas une option.

Voici les problèmes que j’ai pu relever, a priori, en pensant à l’intégration d’images HD :

  • manque de moyens flexibles mis à disposition des développeurs par les fabricants
    • risque de devoir faire de la détection de user agent
    • maintenance du code plus complexe
  • problème de poids des images
    • sites plus lourds en mobilité (Retina sur iPhone4+, iPad, Mac Book)
    • surcharge des serveurs
  • problème de maintenance du site
    • développements plus longs
    • gestion des images et médias plus complexe

Je ne dis pas que cette liste est exhaustive.

Un design nickel chrome

Je n’ai pas mis de majuscule à « chrome » dans le titre, mais j’aurais presque pu.

Bref, blague à part, il y a quelques semaines je vous parlais de l’arrivée de -webkit-image-set() de manière assez concise par ce tweet :

Je vous propose un petit test de cette fonction. Puis nous irons un peu plus loin sur les « images HTML ».

Pour des raisons d’adaptabilité, il m’arrive de plus en plus de placer le logo sur un site web en background CSS, donc pas avec un élément HTML img.
Cette technique me permet de proposer une image légère pour les smartphones et une image plus complexe, grande (et souvent plus lourde) pour des formats plus larges.

De plus si vous regardez un logo classique qui n’a pas subit d’adaptation pour un écran Retina (ou autres HD), il va vous paraitre de moyenne qualité.
Afin de proposer un logo pour Retina sans passer par une media queries, voici un code fonctionnel :

header .logo {
   background-image: url(img/not-supported.png);
   background-image: -webkit-image-set(url(img/logo.png) 1x, url(img/logo-2x.png) 2x);
   background-image: image-set("img/logo.png" 1x, "img/logo-2x.png" 2x, "img/logo-awesome-res.png" 1337dpi);
}

Ici la nouvelle valeur de background-image permet de définir des images sous certaines conditions définies juste après chacune des URL.

J’ai volontairement préfixé uniquement pour webkit car il semblerait que le support ne soit pas (encore) prévu pour les autres navigateurs.
La troisième déclaration de background-image est faite d’après le document en cours de rédaction du W3C sur CSS4 Image. (1337dpi, c’est de l’humour ;))

Cette syntaxe est compatible iOS6 Safari 6 et Chrome 23.
D’après mes tests sous Chrome, seule une image est chargée (chez moi la version « logo.png »).

Images pouvant apparaître dans la démonstration (cliquer pour zoomer)

Démonstration en ligne

Pourquoi image-set et pas media queries ?

C’est une bonne question ! Et en regardant le support de image-set et celui des media queries, la question n’a que plus de force.
Voilà quelques arguments en sa faveur :

  • syntaxe courte
  • permet d’intervenir précisément
  • permet de ne charger que la bonne image tout de suite (testé sur Chrome 23), ce qui n’est pas toujours le cas avec media queries
  • est simplement fait pour ça, et pas autre chose
  • donne un outil en plus des media queries (c’est toujours bien de varier les armes)

Qu’en est-il des « images HTML »

Un groupe de travail est actuellement en train de se tirer les cheveux pour proposer et présenter des solutions possibles pour les images adaptatives.
ResponsiveImages.org

L’élément picture

Cet élément peut, à l’image de l’élément video, accueillir différentes sources.
Ces sources sont utilisées si la condition définie par l’attribut media est respectée.

<picture alt="Texte pertinent">
    <source src="image-small.jpg">
    <source media="(min-width: 20em)" src="image-mid.jpg">
    <source media="(min-width: 40em)" src="image-large.jpg">
    <img src="image-fallback.jpg">
</picture>

La source peut accueillir l’attribut media qui permet de préciser une requête.
C’est une media queries, vous pouvez donc effectuer une requête sur la largeur du viewport, la résolution du device, etc.
L’attribut alt de l’image est porté par l’élément picture et une alternative pour les navigateurs ne supportant pas cette spécification est proposée grâce à l’élément img inséré dans picture.

L’attribut srcset

Cet attribut vient accompagner l’élément img et son attribut src et permet de charger conditionnellement des images.

<img
    src="image-small.jpg"
    srcset="image-mid.jpg 300w, image-large.jpg 2x">

Ici nous avons une image prévue pour les navigateurs qui ne comprennent pas l’attribut srcset (via l’attribut src), puis deux images différentes utilisées selon la condition 300w pour la première (image-mid.jpg) ou 2x, qui correspond à du HD Retina, pour la seconde (image-large.jpg).

Cette syntaxe est partiellement compatible depuis Chrome 34, mais est encore ignorée par les autres navigateurs. Et là où Chrome fait bien son boulot, c’est que seule l’image concernée est chargée. C’est à dire que l’image en src est ignorée si l’un des critères de srcset correspond.

Test et démonstration de srcset

En pratique, il serait possible de définir l’attribut srcset sur une source de l’élément picture également :

<picture>
  <source src="big.jpg">
  <source media="(max-width: 640px)" srcset="small.jpg 1x, small-hd.jpg 2x">
  <img src="fallback.jpg" alt="">
</picture>


srcset n'intervient ici que pour ajouter une condition et une nouvelle source à la première condition définie par l'attribut media.

<update>22/08/2013 : WebKit supporte désormais la syntaxe srcset (source)</update>
<update>09/04/2014 : Chrome 34+ supporte désormais la syntaxe srcset (source), partiellement tout du moins</update>

Mais encore…

Pour ceux qui aiment les choses longues, dures et en anglais, voici un peu de lecture :
HTML Proposals - Responsive images

Sinon il existe aussi une solution partielle avec ce plugin jQuery :
jQuery Responsive img
Plugin a surveiller puisqu'une prochaine version pourrait supporter la HD.

Enjoy !