28118 sujets

CSS et mise en forme, CSS3

Bonsoir !

j'utilise une image en fond pour des liens et la pseudo-classe hover sur ces liens pour modifier le bg.

Du coup, le corps de mon lien pourrait être vide. Mais il est évident que niveau accessibilité c'est pas top (pour les naivgateurs non graphique notamment).

J'ai donc décidé de mettre un <span> dans mon <a> et de mettre le style suivant sur les span :

a#sm_roughs span,a#sm_cg span,a#sm_oxygen span{
    margin-left:-10000px;
}


et dans le code ca donne ca :

<a href="#" id="sm_roughs"><span>Roughs</span></a>
<a href="#" id="sm_cg"><span>C-G</span></a>
<a href="#" id="sm_oxygen"><span>Oxygen</span></a>


Est-ce la bonne technique que de décaler le span ?
Sinon qu'elle est la meilleure technique ?

Merci d'avance
Bonsoir,

Je me suis posé la même question hier soir...
... et j'ai la même question que toi... ("Est-ce la bonne technique ?")

La différence, c'est que j'ai choisi "visibility: hidden" plutôt que "margin-left: -10000px", pensant que cette marge pourrait poser pbm à certains navigateurs (mais je n'en sais rien).
Le "visibility" est-il mieux ? Ou moins bien ?
Ou bien y a-t-il une autre technique à privilégier ?

Question ouverte aux spécialistes de l'accessibilité...
Bonjour,

display:none et visibility:hidden sont à éviter puisqu'ils posent des problèmes d'accessibilité, étant fréquemment interprétés par les lecteurs d'écran qui ont besoin du texte du lien.

L'important, à partir de là, c'est de savoir que toute autre méthode va relever du détournement de CSS Smiley cligne C'est à dire que l'on va utiliser des propriétés pour un autre usage que celui prévu, avec une plus ou moins grande fragilité de résultat, pas de tests d'implémentation systématiques disponibles, et des résultats variables d'un navigateur à l'autre.

C'est pourquoi, en l'absence de "solution miracle" basée sur une propriété unique (du type text-indent, ou margin-left, etc.), la prudence recommande d'utiliser la solution la plus complète. A ma connaissance, c'est encore celle de Bowman, qui est la seule à avoir fait l'objet de tests sérieux.

Voir http://www.blog-and-blues.org/weblog/2004/08/19/277
Le problème avec la méthode FIR (Fahrner Image Replacement), c'est qu'elle trouverait sa limitation si l'utilisateur désactive les images ? Dans ce cas, rien ne s'affiche (ni texte, ni image).



Votre problème, c'est d'avoir des liens graphiques, mais sans nuir à l'accessibilité - et donc d'avoir un texte par défaut pour les navigateurs textuels ?

La solution possible est d'utiliser 'content' :
h1 {

    content: url("image.extension");
    }
mais c'est une propriété de CSS3 (alors les navigateurs commencent à peine à la prendre en charge).




Ce lien vers le blog de Dave Shea (en anglais) donne quelques solutions possibles (Laurent Denis connais ça Smiley cligne ) :
http://www.mezzoblue.com/tests/revised-image-replacement

Il traite de diverses méthodes de remplacement de texte par une image, mais en tentant de conserver la notion d'accessibilité et donc du texte pour les navigateurs non graphiques.

Le principal problème de ces méthodes et de garantir l'accessibilité pour un navigateur où les images sont désactivées (mais qui traite quand même les CSS).

Seule la méthode Levin résout ce problème je crois (l'extrait de code suivant est tiré du livre de Shea/Holzschlag) :

Balisage :
<h1 class="replace" id="myh1">And a dash of Thym.<span></span></h1>


CSS :

.replace {
   position: relative;
   margin: 0px; padding: 0px;
   /* hide overflow:hidden from IE5/Mac \* /

   overflow: hidden;
   /* */
   }

.replace span {
   display: block;
   position: absolute;
   top: 0px;
   left: 0px;
   z-index: 1; /*for Opera 5 and 6 */
   }

#myh1, myh1 span {
   height: 25px;
   width: 300px;
   background-image: url(thyme.png);
   }

Je cite un passage du livre "le zen des css" :

METHODE Levin :
pour : accessible aux lecteurs d'écran. Aucun span superflu. Résolutions du problème des images désactivées lorsque les CSS sont activées.
contre : les images transparentes doivent être évitées *. Lourdeur de la CSS.
prise en charge : widows (IE 5+, Netscape 7, Opera 6+, Firefox) - Macintosh (IE 5.2, Safari, Firefox).


* cette méthode cache le texte derrière une image, si on met une image transparente, le texte est visible derrière.
Modifié par Smiley neko (23 Mar 2006 - 08:57)
Administrateur
neko a écrit :

La solution possible est d'utiliser 'content' :
h1 {

    content: url("image.extension");
    }
mais c'est une propriété de CSS3 (alors les navigateurs commencent à peine à la prendre en charge).

Hmm non seulement c'est effectivement une propriété (CSS2) qui n'est pas prise en charge par beaucoup de navigateurs, mais surtout... il s'agit de CSS.
Or le contenu ne doit pas être véhiculé par quelque couche que ce soit (image d'arrière-plan, CSS, javascript, plugin), puisque dès lors que cette surcouche n'est pas disponible... il n'y a plus de contenu !

Bref, l'essentiel est là :
1- le contenu doit toujours pouvoir être restitué, dans toutes les conditions et sur tous les outils
2- les éléments non pertinents (design, infos complémentaires, comportements, etc.) peuvent être l'objet de surcouches
Raphael a écrit :

Hmm non seulement c'est effectivement une propriété (CSS2) qui n'est pas prise en charge par beaucoup de navigateurs, mais surtout... il s'agit de CSS.


Oui, mais non.

L'extension de la propriété content à tous les sélecteurs relève de CSS3, pas de CSS2. Elle n'est actuellement implémentée que par Opera. Et elle offrirait justement un moyen de régler les problèmes de remplacement de texte par l'image.

Tout comme la possibilité de donner à l'importe quel élément un contenu iconographique en XHTML2.0.

Mais ce n'est pas pour aujourd'hui Smiley cligne
Modifié par Laurent Denis (23 Mar 2006 - 09:53)
Bonjour,

Merci à Laurent Denis et à [ neko] pour les liens...
Après avoir lu attentivement toutes ces références, voilà ce que j'en ai tiré.

Tout d'abord, l'article de Laurent traite du cas d'un logo (ou titre). Il évoque au début le choix (selon des considérations sémantiques ou autres) entre l'utilisation de la balise img et l'utilisation d'un background css.
Dans ce cas, la balise img semble la mieux à même de répondre au problème de l'accessibilité grâce à l'attribut "alt" qui est fait pour ça.
Se poser la question "mon logo/titre fait-il partie intégrante du contenu ou n'est-il qu'un élément de présentation ?" est à mon avis une perte de temps et surtout va amener des réponses diverses selon les personnes, ce qui fait qu'à la fin on ne sera pas plus avancé... Smiley cligne
Bon, donc img, fin du problème.

Sauf que dans certains cas on ne peut pas utiliser img, comme par exemple si l'image du header est un .png transparent (parce qu'il faut dans ce cas penser à IE<7, donc utiliser un background css avec une feuille de style en commentaire conditionnel).
Et on en revient alors au choix de la méthode pour le background css avec un "span" pour ceux qui n'ont soit pas d'images, soit pas de css.
Les deux méthodes proposées dans l'article de Laurent ne permettent pas de traiter le cas où on a les css mais pas les images, comme il est spécifié en conclusion...
(remarque en passant : la méthode du "clip" m'a paru particulièrement horrible Smiley cligne , peut-être plus "élégante" au niveau du html, mais bien lourde côté css...)

On en vient à l'article sur mezzoblue qui semble relativement exhaustif sur le sujet...
Comme l'a signalé [neko ], seule la méthode "Gilder/Levin" semble traiter le cas de la désactivation des images tout en gardant les css.
C'est donc celle que j'ai employée.
(remarque en passant : la méthode décrite ci-dessus par [ neko] (arrgh... mais qui a autorisé les utilisateurs à avoir un "[" dans leur pseudo ! on ne peut plus citer correctement Smiley cligne ...) est différente de celle citée sur mezzoblue : dans le "Gilder/Levin" de mezzoblue, il n'y a pas de "overflow", ni de "z-index", mais en revanche un "width:100%", ceci dit le principe est le même)

Pour ceux que ça intéresse, voici le code auquel j'ai abouti.
Je me replace dans le cadre initial du topic (cf. premier post) qui parlait de lien avec effet hover (donc ce n'est pas un logo, et on ne peut pas utiliser la balise img).
Pour aller jusqu'au bout, j'ai supposé que l'on voulait faire un lien "Accueil" ou "Home" avec un bouton graphique 3 états : état normal, état survolé et état "actif", chacun des états étant représenté par une image différente.

Code php :
<div id="home">
<?php
  if ($page != 'Accueil')
    echo " <a href=\"accueil.php\" title=\"Accueil\"><span></span>Accueil</a>\n";
  else echo " <span><span></span>Accueil</span>\n";
?>
</div>
Partie css (légèrement simplifiée, je vous fais grâce des couleurs par exemple) :
#home a, #home span {
	position: relative;
	display: block;
	width: 90px;
	height: 40px;
	text-align: center;      /* pour centrer sous le bouton, important pour le zoom */
}
#home a span, #home span span {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
}
#home a span {
	background: url(accueil_off.png) no-repeat;
}
#home a:hover span, #home a:focus span {
	background: url(accueil_on.png) no-repeat;
}
#home span span {
	background: url(accueil_active.png) no-repeat;
}
Si on désactive les images et/ou on désactive le css, le texte alternatif situé sous l'image apparait.
On a donc (a priori, car j'ai pas de lecteur d'écran pour confirmer, ni tous les navigateurs pour tester, je fais confiance aux auteurs originaux) résolu le problème.

Les limitations (car comme il est rappelé dans les deux articles, il n'y a pas de méthode miracle unique qui marche dans tous les cas) :
- un "span" vide dans le html.
- si l'image choisie est transparente en son milieu, ça ne marche pas puisque le texte alternatif apparaît en-dessous (en revanche, si elle est transparente uniquement sur les bords, pas de problème).
- un point "oublié" par les auteurs (en tout cas non signalé sur mezzoblue) : à partir d'un niveau de zoom suffisant, le texte "déborde" sous le bouton. Dans mon cas, (avec une taille de 90x40), cela ne se voit qu'à partir des niveaux +8/-6 d'agrandissement/diminution sous FF, donc tout à fait acceptable.

(désolé d'avoir été un peu long... Smiley cligne )