Comment remplacer une image en erreur

Publié le 10 janvier 2017 par Victor Darras | intégration

Cet article est publié sous licence CC BY-NC-SA

Bonjour à tous, aujourd’hui un article très abordable puisque nous allons voir ensemble comment mettre en place un élément de remplacement pour les images afin d’éviter le fameux :

Image qui ne marche pas

Que ce soit pour intégrer cette erreur dans la charte graphique du site, pour la masquer, ou pour en détourner l’usage, il nous faut la possibilité de créer et modifier un élément visuel, avec du texte, plus ou moins stylisé. Malheureusement le support des styles CSS sur une balise <img> est proche du néant. Il va donc nous falloir trouver une alternative.

J’ai eu l’occasion d’expérimenter différentes solutions lors de la création d’une page de monitoring. Pour la petite histoire, l’idée était de charger une même image de différents environnements d’une application. Si l’image est chargée, on l’affiche, si elle ne l’est pas, on indique à l’utilisateur que l’application est down.

Maintenant que nous avons une bonne idée de la problématique, je vais vous présenter 3 solutions différentes.

Commençons l’affichage

Voici les différents exemples des éléments HTML nécessaires à notre exercice. Nous les reverrons au cas par cas.

<section>
  <img alt="Logo de Synbioz" src="https://www.synbioz.com/images/logo-white.svg" />
</section>

<section class="pseudo-elements">
  <img alt="Logo de Synbioz" src="https://www.synbioz.com/images/logo-.svg" />
</section>

<section class="object-tag">
  <object alt="Logo de Synbioz" data="www.synbioz.com/images/logo-svg" type="image/svg+xml">
    <div class="img-placeholder">
      Oups I did it again
    </div>
  </object>
</section>

<section class="img-with-js">
  <img alt="Logo de Synbioz" onerror="this.src='https://synbioz-website-attachments.s3.eu-west-1.amazonaws.com/articles/20170106/Artboard.png';" src="https://www.synbioz.com/images/logo-svg" />
</section>

img:before, img:after {}

Lorsqu’on applique des pseudo éléments à une image, ceux-ci ne sont visibles que si le contenu de la balise n’a pas pu être chargé. De cette manière nous pouvons nous assurer d’afficher un élément de remplacement. Nous pourrions même utiliser un attribut de l’image (alt est un très bon example) pour compléter le message d’erreur par exemple  :

.pseudo-elements img:before {
  content: "Image indisponible : " attr(alt);
  position: absolute;
  padding: 0.25em 0.5em;
  background: #22262c;
  border: 1px solid #4ca5d1;
  color: #4ca5d1;
}

Une fois le chargement de l’image échoué, le navigateur affiche son placeholder : une petite icône avec une image déchirée entourée d’une fine bordure. Ensuite il crée le pseudo élément, le remplit du content et le positionne en absolu pour être sûr qu’il soit affiché au dessus du placeholder. Une fois assuré de cacher le comportement par défaut du navigateur nous avons le champ libre pour ajouter une bordure, un fond ou une couleur de texte.

<object></object>

Une pratique relativement marginale mais qui nous aiderait beaucoup dans ce cas est l’utilisation de la balise <object>. Très utilisée à l’époque de Flash elle permet en fait d’afficher n’importe quel media et donc aussi une image. À la différence de la balise <img> nous pouvons mettre du contenu dans la balise object qui sera chargé si jamais l’URL du média ne répondait pas. Dans notre exemple nous allons utiliser une div avec une classe img-placeholder que nous pourrons styler facilement.

<object alt="Logo de Synbioz" data="www.synbioz.com/images/logo-svg" type="image/svg+xml">
  <div class="img-placeholder">
    Oups I did it again
  </div>
</object>

Nous lui ajoutons n’importe quel style, ce n’est qu’un élément de plus dans le DOM :

.object-tag .img-placeholder {
  display: inline-block;
  padding: 1.25em 1.5em;
  background: #4ca5d1;
  border: 1px solid #fff;
  color: #fff;
}

<img onerror=”javascript”>

Dernière technique, nous allons utiliser l’attribut onerror de la balise image. Cet attribut permet de lancer une fonction ou simplement du code JavaScript lorsque le chargement de l’image est en erreur. Ainsi, nous pouvons nous assurer de remplacer l’image de base (dont l’existence n’est pas définie) par une image que nous avons préselectionné.

L’image de base sera celle présente sur l’environnement distant qui — s’il ne répond pas — ne renvoie rien. On change alors l’URL de l’image pour en récupérer une dans la base d’images de l’application locale.

this.src='https://synbioz-website-attachments.s3.eu-west-1.amazonaws.com/articles/20170106/Artboard.png';

Le this correspond à l’élément courant (l’image donc), le .src sélectionne l’attribut src correspondant que nous remplissons avec une URL connue de notre application.

En conclusion

Maintenant que nous avons décrit toutes ces techniques, voici un aperçu des différents rendus :

See the Pen Image Replacement Techniques by Victor Darras (@victordarras) on CodePen.

Avec ces 3 solutions différentes, j’espère vous avoir ouvert les yeux sur les possibilités peu répandues des styles et remplacements d’images. N’hésitez pas à tester ces différentes solutions pour trouver celle qui répondra à vos besoins. N’hésitez pas à partager vos cas d’usage et vos remarques dans les commentaires si cet article vous a plu.

L’équipe Synbioz. Libres d’être ensemble.