Une solution CSS accessible pour remplacer du texte HTML par une image

Dans l’article remplacer du texte HTML par une image avec CSS, j’ai listé un certains nombre de techniques efficaces permettant d’avoir un titre de niveau `h1` (par exemple) qui disparait de l’affichage au profit d’un visuel plus «sexy». Le but étant d’améliorer l’apparence du site et le référencement dans les moteurs de recherche. Toutefois, les solutions présentées n’offrent pas toujours une expérience utilisateur satisfaisante pour tous. Les utilisateurs de lecteurs d’écran comme Jaws ou NVDA risquent de ne pas y trouver leur compte. Certaines solutions sont «accessibles» uniquement lorsque les CSS sont désactivées et il faudra penser aux cas où les images sont absentes.

Une solution satisfaisante devrait permettre de garder un document intelligible lorsque les feuilles de styles et les images sont désactivées, mais aussi lorsque l’une ou l’autre seulement est active. Pour cela, il suffit de placer le texte en question derrière l’image via la propriété `z-index` pour jouer avec la profondeur. De cette manière, le texte apparait lorsque les images et/ou les feuilles de styles CSS ont été désactivées par l'( agent ) utilisateur.

Marquage HTML & CSS

Voici un exemple que j’ai testé en situation réelle pour m’assurer que cette solution n’entrainait pas d’effets de bord sur le reste de la page. Voici donc la partie de l’en-tête avec un logo et une description en mode texte, et une image en dur pour avoir un bon vieil attribut `alt` des familles comme on les aime !

<header>
    <hgroup>
        <h1 id="logo"><a href="/" rel="home">Salut, c'est moi : logo !</a></h1>
        <h2 id="motto">Salut, c'est moi : motto !</h2>
    </hgroup>
    <div id="banner">
        <a href="/"><img src="images/logo.png" alt="CSS & Webdesign" width="940px" height="150px"></a>
    </div>
</header>
header {
    position: relative;
    height: 170px;
}
hgroup {
    position: absolute;
    z-index: 1;
    top: 25px;
    left: 1px;
}
#banner {
    position: absolute;
    z-index: 2;
}

Dans un premier temps, la déclaration position: relative sur l’élément `header` permet de placer `hgroup` et `#banner` en position absolue par rapport à `header` et non au Viewport. La valeur de `height: 170px` remplace la hauteur qu’aurait du avoir `header` si les éléments qu’il contient n’avait pas été sortis du flux par le positionnement absolu.

Les éléments `hgroup` et `#banner` sont positionnés de manière absolue pour permettre d’utilisation de la propriété `z-index`. Quant à `hgroup`, il est en `z-index: 1` pour permettre aux liens qu’il contient de rester cliquables (ce qui ne serait pas le cas, s’il leur `z-index` était inférieur à zéro).

L’image contenue dans `#banner` est en `z-index: 2`, ce qui la place au-dessus des éléments contenus dans `hgroup`. Le décalage en `top` et `left` sert à positionner précisément `hgroup` derrière l’image, selon ses dimensions. Le `left: 1px` empêche les serifs de certaines polices de caractères de dépasser de l’image.

Aperçu du composé HTML & CSS en images

Après le code, voici le résultat des courses en image avec les différentes cas de figure que l’on peut rencontrer :

  1. Avec CSS et images,
  2. Avec  image sans CSS,
  3. Sans image mais avec CSS,
  4. Sans image et sans CSS.

CSS et images activées

Le logo texte et la description se retrouve derrière l’image conformément à leurs propriétés z-index respectives.
Fig. 1 : CSS et images activées. Cliquez pour agrandir l'image.

Avec images sans CSS

L’absence de CSS annule les propriétés de positionnement dans le flux et d’empilement des éléments.
Fig. 2 : image activée, CSS désactivée. Cliquez pour agrandir l'image.

Sans images avec CSS

Si les images sont désactivées, les propriétés position: absolute et z-index continuent de jouer leur partition.
Fig. 3 : CSS activée, image désactivée. Cliquez pour agrandir l'image.

Sans image et sans CSS

Le grand jeu ! Voici le header en l’absence de toute fioriture : plus d’image et plus de CSS !
Fig. 4 : image et CSS désactivées. Cliquez pour agrandir l'image.

Conclusion

Cette solution est loin d’être parfaite, notamment en raison de l’utilisation du positionnement absolu dont je ne suis pas fan ou du moins que j’évite en général pour les éléments structurels d’une page. Il existe certainement d’autres manières de placer du texte derrière une image en faisant en sorte que l’accessibilité des uns et des autres ne soit pas compromise.

Merci à Sébastien Delorme et à Sylvain Fix qui ont inspiré ce billet grâce à leurs commentaires.

A suivre 🙂