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 :
- Avec CSS et images,
- Avec image sans CSS,
- Sans image mais avec CSS,
- 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.
Avec images sans CSS
L’absence de CSS annule les propriétés de positionnement dans le flux et d’empilement des éléments.
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.
Sans image et sans CSS
Le grand jeu ! Voici le header en l’absence de toute fioriture : plus d’image et plus de CSS !
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 🙂
Très bonne solution. Merci Bruno
Concernant ta solution, je ne pense pas que l’approche soit correct … du moins en ce qui concerne ton example.
Du point de vue de l’accessibilité l’utilisation d’une image comme alternative ne se justifie pas. Le texte, comme pour l’attribut alt de ton image, ne reflète pas du tout l’information textuel qui est caché. Il s’agit d’un élement purement design, non? Dans ce cas, tu peu utiliser une image d’arrière plan à l’aide d’une simple balise span. Il n’est pas non plus nécessaire d’utiliser les ID. La structure XHTML est suffisament propre pour être utilisé à l’aide de simple règles css. De plus, dans l’example ci-dessous, tu évites de répéter l’adresse url ou l’information alt/texte pour les lecteurs d’écran.
Salut, c’est moi : logo !
<h2>Salut, c'est moi : motto !</h2>
</hgroup>
hgroup,
hgroup span{
position:absolute;
z-index:1;
top:25px;
left:1px;
height:170px;
width:XXXpx;
overflow:hidden; /* pour les personnes utilisant la fonction « zoom » du navigateur afin de ne pas casser ton « layout » */
}
hgroup span{
display:block;
left:0;
top:0;
background:url(image) transparent left top no-repeat;
}
Salut,
Oui, l’exemple est un peu bidon, comme le suggère le « salut, c’est moi : logo… », etc. pour montrer qu’en l’occurrence chacun devra adapter cette idée à son cas particulier.
Dans certains cas, il vaudra mieux utiliser un background, mais ici, comme il s’agit du logo, je pars du principe qu’il doit être visible y compris lorsqu’on désactive les images.
Ll’intérêt de cette solution est justement de préserver le maximum de choses, que l’on désactive au choix les css, les images ou les deux !)
Avec
ce code HTML/CSS, les liens h1>a et #banner>a sont doublonnés
pour les lecteurs d’écran et dans les 3 cas sans images et/ou CSS, du
moins avec un exemple correct où h1>a et #banner>a>img[alt]
auraient le même contenu et l’image représenterait bien le logo du site
et/ou serait clairement identifié comme le lien de retour à l’accueil.
Si h1 est un lien de retour à l’accueil (OK, c’est un classique) et h2
du texte, autant découper le header en 2 images, l’une cliquable l’autre
pas avec les alt qui vont bien. OK ça fera 2 images à charger au lieu
d’une, c’est pas optimal niveau performance web mais c’est pas la mort
non plus, il y a de quoi se rattrapper sur le reste des pages 🙂 et par
contre c’est de l’accessibilité tout-terrain à base de HTML et CSS on ne
peut plus classiques. Il n’y a aucune « technique » particulière (dans le
sens astuce) en fait. 2 textes, 2 images et leurs [alt]
J’ai une autre approche et c’est ce que je fais quand j’ai besoin qu’un site soit accessible, la différence, c’est que je pars du principe où les balises IMG sont uniquement utilisé pour les images lié aux contenu/articles. Pas de balises IMG pour le logo ou tout autres éléments de décor.
http://jsfiddle.net/PooLP/VQ6SN/4/
Cette solution évite la redondance d’informations et simplifie le markup.
Bon en fait, je suis un peu hors sujet, surtout concernant la désactivation des images … il y un intérêt à ne désactiver que les images ?
Bien sûr qu’il y a un intérêt à ne désactiver que les images : conserver la présentation, la mise en forme et le positionnement des éléments.
Prenons l’exemple d’une personne malvoyante qui a besoin de lire sur un contraste fond rouge et texte noir. L’objectif est de ne changer que les couleurs, pas nécessairement la mise en page (pour pouvoir profiter du design prévu).
Par exemple, lorsque les contrastes élevés sont activés dans Windows les navigateurs affichent une page Web en :
– Remplaçant toutes les couleurs de texte (du noir dans mon exemple) ;
– Remplaçant toutes les couleurs de fond (du rouge dans mon exemple).
Dans ce cas de figure, l’utilisateur pourrait rencontrer des problèmes si initialement une image d’arrière-plan rouge était utilisée car le texte rouge se retrouverait sur un fond rouge.
Du coup, le comportement du navigateur est également de retirer toutes les images de fond pour les remplacer par une couleur (du noir dans mon exemple).
Pour tester, rien de mieux que d’activer le contraste élevé sur Windows et de naviguer sur une page remplie d’images de fond et de texte caché (http://www.tesco.com/ par exemple).
Sébastien.
Et comme un dessin vaut mieux qu’un long discours :
– Tesco affiché par défaut : http://www.diigo.com/item/image/244do/bswi
– Tesco lorsque le contraste élevé est activé : http://www.diigo.com/item/image/244do/npys
Sébastien.
Ok, merci pour ta réponse, je n’avais pas cette vision 😉
Par contre, existe-t-il un comparatif d’utilisation ? En gros, est-ce qu’il y a beaucoup d’utilisateurs malvoyant qui utilisent les fonctions natives des navigateurs pour l’accessibilité ou vont-ils préférer utiliser un lecteur d’écran, car ce que propose Bruno amène une redondance d’informations qui ne me plait pas.
Le logo d’un site n’est pas du « décor » au sens image de décoration dont on pourrait se passer : c’est là où se trouve le nom du site ! Voir une page affichée et ne même pas savoir à quel site elle appartient serait moyen …
Et si c’est un lien de retour à l’accueil, cas très très courant, c’est même indispensable que le lien ne soit pas vide.
Si tu regarde mon exemple, le nom du site apparaît, il est juste caché via un text-indent, mais si je cache uniquement les images, le texte n’apparaît pas :O
Bonjour,
Je ne sais pas si c’est que je ne suis pas du matin, mais je n’ai rien compris à ce billet 🙂
Tu utilises du texte caché et une balise avec une alternative.
Dans ton exemple, la balise suffit amplement donc ?
Je crois que j’ai besoin d’éclaircissements…
Bonjour,
Dans l’exemple qui est proposé, en plus du problème déjà soulevé par Felipe (contenu doublonné pour les lecteurs d’écran), un autre problème persiste.
En superposant une image (ici logo.png) à un élément pouvant recevoir le focus (ici
<h1 id="logo">
) on prend le risque de dérouter les utilisateurs naviguant au clavier : la prise de focus sur<h1 id="logo">
peut être couverte par la superposition de l’image logo.png ; donc invisible.En résumé, l’internaute à l’impression de tabuler une fois « dans le vide » et perd potentiellement le fil de sa navigation.
En accessibilité, rien n’est plus robuste qu’une bonne vielle image déclarée dans le HTML avec un attribut alt correctement renseigné.
@ sebastien : Je pense que la raison principale de cette proposition est pour de « l’optimisation » SEO.
Comme le sujet est hyper intéressant (merci Bruno), j’ai fait des tests ce midi (http://jsfiddle.net/PooLP/VQ6SN/) et j’arrive à peu près à la même technique que Bruno, la différence est que mon logo ‘image’ est mon logo ‘texte’ est au même niveau … mais je n’aime pas utiliser ‘position:absolute’.