Images & Responsive Web Design Les logos d’Articles

, par Cédric

Comment gérer l’affichage des logos d’articles dans un site SPIP Responsive.

Le développement de sites Responsive [1] est une problématique de plus en plus fréquente : le RWD (Responsive Web Design) est une réponse pragmatique et économiquement réaliste à la diffusion de l’information sur toutes les plateformes et types d’écrans (mobiles, tablettes, ordinateurs…).

Cependant la gestion des images en RWD reste un problème technique complexe car HTML ne propose pas (encore) de solution pour cela. Des propositions techniques sont à l’étude, mais il faudra encore attendre longtemps avant qu’un éventuel markup dédié à cet usage (balise HTML et/ou attribut) soit supporté par tous les navigateurs en usage.

Nous allons voir dans ce billet quelles techniques nous pouvons mettre en place pour l’affichage des logos (d’articles ou de rubriques etc.).

Les logos SPIP images illustratives au rôle bien particulier

Dans SPIP, les logos sont des images qu’on peut téléverser sur chaque article, rubrique… et qui servent en général comme petite (ou grande) illustration dans les listes.

Ces logos ne sont pas porteurs de sens : ils n’ont habituellement pas de texte alternatif dans le squelette par défaut de SPIP. Ce sont de simples repères visuels décoratifs dans les listes, qui servent alors de points d’accroches pour l’œil au sein d’une page qui peut-être fournie.

Du fait de cet usage, on veut parfois masquer ces logos :

  • en fonction du contexte : certaines listes compactes ne nécessitent pas ces repères
  • en fonction de la taille de l’écran : sur de petits écrans ces images prennent inutilement de la place et gênent la navigation dans la page au contraire

Enfin, ces images sont en général de taille modeste.

Dans un site responsive, on va donc vouloir masquer ces logos dans certains cas, à l’aide de media-queries. Évidemment, ces images ne devront pas être téléchargées par le navigateur dans ce cas de figure.

Chargement des images dans les navigateurs

Les navigateurs modernes sont optimisés pour charger et afficher les pages web le plus vite possible. Pour faire cela ils ont pour stratégie de lancer le chargement de toutes les balises <img> présentes dans le code source HTML, sans s’occuper des feuilles de style. Pour en tenir compte il faudrait attendre de construire le DOM, recevoir toutes les feuilles de style et les interpréter, ce qui serait trop long.

En conséquence, une simple directive img {display:none} n’empêche nullement que l’image soit téléchargée.

Heureusement pour nous, certains se sont déjà penchés sur cette question et ont testé différentes construction HTML dans de larges panels de navigateurs pour voir de quelle façon on peut éviter de charger une image qu’on ne veut pas afficher.

Sans grande surprise, on voit qu’il faut passer par une directive CSS affichant l’image en background. Mais même de cette façon il convient d’avoir une construction à 2 niveaux avec un conteneur et un contenu, le second portant l’image et le premier recevant la directive d’affichage/masquage.

Version 1 <img> dans un <span>

Le code HTML généré par SPIP pour afficher un logo d’article (obtenu par #LOGO_ARTICLE) est nativement une simple balise <img> :

L’idée initiale est de conserver cette image, pour rester au plus près du code initial. Pour pouvoir contrôler le chargement l’image affichée passerait via un attribut style, et l’attribut src ne mentionnerait qu’un simple gif transparent en Data URI pour éviter un hit externe.

Cela donne, au plus simple :

On note que la classe spip_logos est déplacée de la balise <img> vers le conteneur <span> car c’est elle qui porte les styles éventuels de mise en forme des logos.

Manque de chance cela aurait été trop facile : nos feuilles de styles contiennent en général une directive du type
img {max-width:100%;height:auto}.
Ici la directive height:auto est interprétée par rapport à l’image indiquée dans l’attribut src et pas par rapport aux attributs height et width. Notre image src faisant 1px x 1px, le navigateur suppose une image carrée, et on se retrouve avec un logo de 150px x 150px.

Il nous faudrait donc forcer la hauteur de l’image au moyen d’une directive height dans l’attribut style.
Mais dans ce cas la hauteur de l’image est figée et ne s’adapte plus quand on modifie sa largeur par la feuille de style (logo trop grand par rapport à la taille de l’écran, ou contenu dans une grille dont la largeur change en fonction de l’écran).

Il nous faut donc réviser cette proposition.

Version 2 ça se complique avec un <span> de plus

Le problème étant de respecter le rapport hauteur/largeur de l’image en cas de redimensionnement, tournons nous vers la technique de l’intrinsic-ratio renommée aussi plus simplement padding-bottom-hack.

Cette technique consiste à avoir 2 conteneurs : le premier fixe la largeur, le second fixe le ratio largeur/hauteur grâce à une astuce CSS consistant à lui fixer un height nul et un padding-bottom relatif qui est alors proportionnel à la largeur du conteneur.

Appliqué à notre logo, cela donne alors le code suivant à 3 étages :

Le premier span porte la largeur, le second le rapport largeur/hauteur et <img> porte l’image.

OK, cette fois nous avons bien notre logo qui s’adapte en largeur et se redimensionne en fonction des directives CSS.
A noter que le le premier span ne porte pas de directive display:block qui serait prioritaire sur un éventuel .spip_logos {display:none} présent dans la feuille de style.
Par défaut notre logo prendra donc toute la largeur de son conteneur, sauf si on lui applique une directive CSS de type display:block ou une directive float. Dans ce cas la largeur indiquée dans l’attribut style sera respectée.

A l’épreuve des tests, il reste néanmoins un cas dans lequel notre logo ne s’affiche pas correctement : sous IE7 qui n’interprète pas les DATA URI. Du coup, celui-ci ne rend pas l’image ni son background et l’on se retrouve avec une zone blanche.

Version 3 plus simple, sans <img>

Après quelques essais il apparait que pour IE7 la seule solution est de placer l’image en background CSS sur le second <span> et non sur la balise <img>.

Celle-ci n’ayant alors plus de sens, ne portant aucune sémantique, et étant masquée, nous l’enlevons, ce qui nous permet de simplifier le code utilisé :

Nous appliquons au passage une class img sur le <span> de second niveau, ce qui permet de le cibler en CSS de manière plus efficace si nécessaire.

Au final cette construction donne satisfaction :

  • on peut masquer notre logo sans qu’il ne soit chargé par le navigateur au moyen de la règle CSS .spip_logos {display:none;}
  • on peut forcer la largeur du logo dans les feuilles de style, avec une règle du type : .spip_logos {max-width:25%;float:right}

Un filtre SPIP pour faciliter l’utilisation

Pour faciliter l’utilisation de cette technique, on propose le filtre responsive_logo utilisable simplement dans un squelette SPIP sous la forme suivante [2] [3] :

Il est utilisé sur la page d’accueil de ce blog ainsi que sur la toute nouvelle version responsive de Basta !.

Ce filtre est nativement disponible et utilisé par le framework SPIPr dédié à la construction de sites SPIP responsive à l’aide de BootStrap.

Et mes images de contenu alors ?

Si notre solution permet de traiter la question des logos sur un site responsive, elle ne peut s’appliquer aux images de contenu pour lequel le besoin est différent : charger la bonne taille d’image en fonction de la taille de l’écran, tout en respectant la sémantique de la balise <img>.

Aucune solution miracle n’existe à ce jour pour les images de contenu, mais nous verrons dans un prochain billet les alternatives à notre disposition.


Photo par Widianto Nugroho sous licence CC-by-nc-nd

Notes

[1c’est à dire dont l’affichage s’adapte à la taille de l’écran

[2ce filtre prend également en charge les logos au survol, dont nous n’avons pas parlé ici, qui reposent sur 2 attributs javascript

[3on aurait pu modifier directement le comportement de #LOGO_ARTICLE, mais ce serait présumer de l’usage exclusif des logos à titre d’illustration masquable, ce qui n’est pas toujours le cas