accueil navigation contenu

Delavy for the Web

Reflexions bilingues pour améliorer le Web

Version FrançaiseEnglish Version

Pour un bon affichage de hreflang

samedi 13 juin 2009 [16:33:30]

Voici 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.

  1. Langue du parent
  2. Langue du lien
  3. Méthodes combinées
  4. Optimisation
  5. La bonne cascade
  6. Tableau de contrôle

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.

1° Langue du parent du lien

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 :

  1. On peut faire plus simple en utilisant le sélecteur not()[01] en CSS, mais il n'est pas encore bien implémenté ( pas sur ie6-7-8 ni Opéra)[02].
  2. C'est la seule méthode qui fonctionne sur IE7.
  3. Si je procède par exclusion, c'est pour que mes règles s'appliquent quel que soit le contenu de 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).

2° Langue du lien

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.

3° Méthodes combinées

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 :

  • On affiche hreflang pour tous les liens qui ont les attributs hreflang et lang, sans tenir compte de la langue parente.
  • On masque 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"

4° Optimisation.

Toujours dans l'optique de créer une règle générale, nous pouvons ajouter quelques exclusions :

  • On enlève 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="").
  • On annule la règle pour les titres : le contenu généré est souvent peu maniable en CSS, ce qui peut poser problème quand les titres sont placés au pixel près. Et ce n'est pas non plus toujours très esthétique.
/* 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;
}

5° La bonne cascade

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;
}

6° Tableau de contrôle

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.

contrôle de la règle (en violet les cas peu probables)
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

Notes et références:

  • Cette règle est très pratique dans le style interne de Firefox (UserContent.CSS).
  • Pour préciser la langue, un texte vaut largement mieux qu'un drapeau. Un drapeau désigne un pays, pas une langue !
  • Ici j'utilise du texte, mais Pompage.net fait des merveilles avec une image.
commentaires: (ajouter)
contributeur: payday loan
date: 2015-09-17 11:42:53
lumhlimy payday loan

contributeur: 90 day payday loans
date: 2015-07-22 10:57:29

contributeur: payday loans
date: 2015-03-30 04:19:06
smlphebs payday loans

contributeur: buy viagra
date: 2015-03-27 08:14:23
pczjhnm buy viagra

contributeur: payday loans
date: 2015-02-17 20:42:51
scgampm payday loans

contributeur: payday loans
date: 2014-12-16 23:18:26
hxoasj payday loans

contributeur: mobile loans
date: 2014-09-20 01:44:49
vhvelzbb mobile loans

contributeur: 24 hour loans
date: 2014-06-26 11:02:57
kuiucip 24 hour loans

contributeur: no credit check loans
date: 2014-05-24 15:40:44

contributeur: loans with bad credit
date: 2014-05-10 13:23:16

contributeur: payday loans
date: 2013-12-05 00:40:49
nitzqar payday loans

contributeur: payday loans
date: 2013-11-15 04:37:31
gmeiruzj payday loans

contributeur: dLYWYz9GxENd
date: 2013-09-28 16:07:15

contributeur: payday loan
date: 2013-09-28 04:51:41
vzentwx payday loan

contributeur: FRT7ygS1QQT
date: 2013-09-19 22:14:46

contributeur: ogkABgPkzq
date: 2013-09-06 12:04:47

contributeur: gibzpD3dqMzF
date: 2013-08-29 03:38:16

contributeur: hMuPVTxy0
date: 2013-08-26 23:22:46

contributeur: aHRsaCGI
date: 2013-08-19 04:11:30

contributeur: SBuYAyFfE
date: 2013-08-17 03:45:19

pour obtenir le code de validation ne conserver que les lettres et chiffres en majuscules de cette expression: cWeeGaaaYcccWbbZ >>  

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