Reflexions bilingues pour améliorer le Web
Version FrançaiseEnglish VersionVoici une méthode CSS pour afficher la langue cible d'un lien (l'attribut hreflang) à côté de celui-ci. Cette langue cible est une information essentielle, surtout quand elle est différente du texte qui contient le lien. On peut l'afficher en "contenu généré par CSS", avec une combinaison de règle qui offre une méthode très souple qui prend en compte de nombreux cas de figure. Vous pouvez retrouver ce style sur userstyle.org.
This article is available in an English version.
On cherche à afficher la langue cible d'un lien quand celle-ci est différente de la langue du texte qui contient le lien. Mais il existe de nombreux cas de figures selon les attributs renseignés... Pour ceux qui sont pressés, voilà la bonne solution. Pour les autres, nous allons découvrir comment on y arrive.
En CSS, on sélectionne la langue parente d'un élément en utilisant [lang="fr"]. La règle dit "dans un contenu en français, les liens qui pointent vers autre chose que du français, il faut mettre l'attribut hreflang à côté, (et même chose pour l'anglais)". Elle se traduit en CSS par :
/* J'affiche hreflang */
a[hreflang]:after{
content: " ("attr(hreflang)")";
}
/* Je l'enlève quand c'est la même langue */
[lang="fr"] a[hreflang="fr"]:after,
[lang="en"] a[hreflang="en"]:after{
content:none;
}
Notes :
not()[01] en CSS, mais il n'est pas encore bien implémenté ( pas sur ie6-7-8 ni Opéra)[02].hrefelang. Sinon, il faudrait une déclaration par langue de lien supposée, alors qu'ici il ne faut qu'une règle par langue d'édition. Cette méthode ne fonctionne que si la langue n'est spécifiée qu'une fois. Or un lien peut avoir plusieurs ancêtres : un parent proche en français (langue de l'article), et un parent éloigné en anglais (langue du site). Dans ce cas, les résultats seront aléatoires. Voir l'exemple :
<body lang="en"> <p>[...] english content [...]</p> <div lang="fr"> <p>[...] contenu français [...]<br /> Allons sur <a hreflang="fr" href="#">google en français</a><br /> Essayons <a hreflang="en" href="#">google en anglais</a></p> </div> </body>
Ce pre donne
[...] english content [...]
[...] contenu français [...]
Allons sur google en français
Essayons google en anglais
Dans ce cas, dans le texte en français, le lien pointant vers du français [03] prend aussi l'attribut puisqu'il est enfant d'une div anglaise. Changer l'ordre des déclarations ne ferait que remettre le problème au cas inverse (et cela ne fonctionnerais pas pour 3 langues).
On sélectionne la langue d'un lien, qu'il héritera de son plus proche parent, avec :lang(fr) (pour du français). Cette pseudo-classe ne tient pas compte des éventuels parent multiples et interprète la dernière langue attribuée : un texte est soit français, soit anglais. La règle donne : "un lien en français qui ne pointe pas vers du français, il faut mettre l'attribut hreflang à côté, même chose pour l'anglais". Elle se traduit en CSS par :
/* J'affiche hreflang */
a[hreflang]:after{
content: " ("attr(hreflang)")";
}
/* Je l'enlève quand c'est la même langue */
a[hreflang="fr"]:lang(fr):after,
a[hreflang="en"]:lang(en):after{
content:none;
}
L'ennui est que parfois, le lien qui pointe vers de l'anglais lui même est en anglais. Par exemple, vous reprenez comme intitulé du lien le titre de l'article sur lequel vous pointez.
<body lang="en"> <p>[...] english content [...]</p> <div lang="fr"> <p>[...] contenu français[...]<br /> Allons sur <a hreflang="fr" href="#">google en français</a><br /> Essayons <a hreflang="en" href="#">google en anglais</a><br /> Un article : <a hreflang="en" lang="en" href="#" >"I love Mozilla"</a></p> </div> </body>
Ce pre donne :
[...] english content [...]
[...] contenu français[...]
Allons sur google en français
Essayons google en anglais
Un article : "I love Mozilla"
Ici, pour le troisième lien (vers l'article en anglais), la langue du corps du lien est l'anglais. C'est donc la seconde règle qui s'applique (Je l'enlève quand c'est la même langue) et lui enlève l'attribut. Il faudrait en fait que l'on identifie la langue du plus proche parent du lien pour écrire une règle générale.
Nous allons donc reprendre la deuxième règle, et régler les problèmes en ajoutant d'autres déclarations (vous vous en doutiez, non ? ).
Il faut créer une règle pour afficher l'attribut hreflang quand dans le lien, les deux attributs lang et hreflang sont spécifiés, et que la langue cible dans hreflang soit différente de la langue du conteneur. Deux étapes sont nécessaires :
hreflang pour tous les liens qui ont les attributs hreflang et lang, sans tenir compte de la langue parente.hreflang pour les liens dont le plus proche parent à la même que celle du spécifiée pour le lien.
/*Quand il y a lang et hreflang, j'affiche hreflang*/
a[lang][hreflang]:after{
content: " ("attr(hreflang)")";
}
/*Je l'enlève quand c'est la même langue que le plus proche parent.*/
:lang(en)>a[lang="en"]:after,
:lang(fr)>a[lang="fr"]:after{
content:none !important;
}
Et voilà :
<body lang="en"> <p>[...] english content [...]</p> <div lang="fr"> <p>[...] contenu français[...]<br /> Allons sur <a hreflang="fr" href="#">google en français</a><br /> Essayons <a hreflang="en" href="#">google en anglais</a><br /> Un article : <a hreflang="en" lang="en" href="#" >"I love Mozilla"</a></p> </div> </body>
Ce pre donne :
[...] english content [...]
[...] contenu français [...]
Allons sur google en français
Essayons google en anglais
Un article : "I love Mozilla"
Toujours dans l'optique de créer une règle générale, nous pouvons ajouter quelques exclusions :
hreflang quand l'attribut est vide. En effet, a[hreflang] sélectionne les liens dans lesquels on trouve l'attribut hreflang, mais il peut être vide (ex : hreflang="").
/* Je l'enlève quand il est vide */
a[hreflang=""]:after{
content:none !important;
}
/* Je l'enlève quand c'est un titre*/
h1 a[hreflang]:after,
h2 a[hreflang]:after{
content:none !important;
}
La bonne cascade, compactée :
/* 1 - Je met le contenu après les liens qui ont hreflang */
a[hreflang]:after{
content: " ("attr(hreflang)")";
}
/* 2 - Je l'enlève quand c'est la même langue */
a[hreflang="fr"]:lang(fr):after,
a[hreflang="en"]:lang(en):after{
content:none;
}
/* 3 - Quand il y a une langue et une langue cible, j'affiche hreflang */
a[lang][hreflang]:after{
content: " ("attr(hreflang)")";
}
/* 4 - Je l'enlève quand c'est dans la même langue */
:lang(en)>a[lang="en"]:after,
:lang(fr)>a[lang="fr"]:after,
/* 5 -...quand il est vide... */
a[hreflang=""]:after,
/* 6 - ...et quand c'est un titre. */
h1>a[hreflang]:after,
h2>a[hreflang]:after,
h3>a[hreflang]:after{
content:none !important;
}
Et la voici en version simplifiée, avec not() et (pas compatible IE ni Opera). Comme la langue peut être spécifiée avec un attribut régional (en-us pour l'anglais des Etats Unis), j'utilise un selecteur CSS3 qui permet de spéficier "qui commence par" : ^. On écrit donc [lang^="fr"] pour parer à toutes éventualités.
/* J'affiche hreflang quand la langue cible est différente de la langue du texte */
a[hreflang]:not([hreflang="fr"]):lang(fr):after,
a[lang^="fr"]:after,
a[hreflang]:not([hreflang^="en"]):lang(en):after,
a[lang^="en"]:after{
content: " ("attr(hreflang)")";
}
/*Je l'enlève quand il y a juste une langue et pas de langue cible,
ou quand il y a la même langue */
:lang(en)>a[lang]:not([hreflang]):after,
:lang(fr)>a[lang]:not([hreflang]):after,
:lang(en)>a[lang^="en"]:after,
:lang(fr)>a[lang^="fr"]:after{
content:none;
}
/* Sauf quand c'est vide... */
a[hreflang=""]:after,
/* ...ou quand c'est un titre*/
h1>a[hreflang]:after,
h2>a[hreflang]:after,
h3>a[hreflang]:after{
content:none !important;
}
Le tableau permet de contrôler le bon fonctionnement de la règle. Si on utilise la version simplifiée, la dernière colonne avec "de" n'est pas correcte, il faudrait dupliquer les déclarations pourlang(de) dans le pre CSS.
| Langue de la ligne | hreflang en | lang en | hreflang en lang en |
hreflang es | lang es | hreflang es lang es |
hreflang fr lang en |
hreflang en lang fr |
hreflang fr lang de |
hreflang de lang fr |
|---|---|---|---|---|---|---|---|---|---|---|
| non précisée tableau en anglais |
Link | Link | Link | link-es | link-es | link-es | Link | Lien | link-de | Lien |
| Anglais | Link | Link | Link | link-es | link-es | link-es | Link | Lien | link-de | Lien |
| Français | Link | Link | Link | link-es | link-es | link-es | Link | Lien | link-de | Lien |
| Espagnol | Link | Link | Link | link-es | link-es | link-es | Link | Lien | link-de | Lien |
Textes, images et design : Copyright © 2008 - 2009 Delaby Pierre.
Copyleft : cette oeuvre est libre, vous pouvez la redistribuer et/ou la modifier selon les termes de la Licence Art Libre. Vous trouverez un exemplaire de cette Licence sur le site Copyleft Attitude www.artlibre.org ainsi que sur d'autres sites.
Icons par Mark James sous Creative Commons | Tous les Crédits et Attributions.
Généré avec Logz : http://www.logz.org | Hebergé par Provisoire.fr | Copyleft Licence Art Libre | Vrs ?, Vxl ? | site map