Personnaliser les liens

En surfant, je remarque de plus en plus souvent des liens avec des icônes devant et un indicatif de langue. Je me suis donc un peu penché dessus en essayant d'automatiser les choses. Parce que le plus simple, c'est évidemment de créer des styles pour chaque type de lien. Mais on va voir comment on peut faire pas mal de choses en CSS aussi.

Quelques bonnes pratiques

D'après les bonnes pratiques 52 et 50, il faut que les liens internes, externes et visités soient différenciés visuellement. On va essayer d'obtenir ça :

Illustration de ce qu'on veut obtenir

Les liens internes

On peut par exemple partir du principe que par défaut, tous les liens sont internes :

a {
	background: url(images/link_intern.png) no-repeat;
	padding-left: 16px;
}

Les liens visités

Ensuite, les liens déjà visités :

a:visited {
	background: url(images/link_visited.png) no-repeat;
}
 

Les liens externes

Maintenant, comment savoir si un lien est externe ? Pour ça, on peut vérifier dans le href si l'URL est absolu ou relatif si on part du principe que toutes les URL internes doivent être écrites en relatif. On pourrait aussi vérifier le nom de domaine du lien pour voir si c'est un lien interne, mais on ne va pas le faire dans cet exemple.

Bref, pour repérer les liens externes, on va utiliser un sélecteur un peu particulier :

a[href^="http:"] {
	background: url(images/link_extern.png) no-repeat;
}

Cela sélectionne les balises a qui ont un attribut href qui commence par http:. Pour avoir plus de détails, vous pouvez consulter la documentation.

Les liens e-mail

Même principe que les liens externes :

a[href^="mailto:"] {
	background: url(images/link_mail.png) no-repeat;
}

Problèmes

Et oui, il y en a. Pour l'instant, j'en ai listé 3 :

  1. les ancres
  2. un lien sur une image
  3. un lien dans un titre

Les ancres

Le problème, c'est que les ancres utilisent la balise a aussi, mais ils n'ont pas de href. Il suffit donc de filtrer sur ça, on remplace donc la style des liens internes par :

a[href] {
	background: url(images/link_intern.png) no-repeat;
	padding-left: 16px;
}

Lien sur une image

C'est sympa les icônes devant les liens, mais on en veut pas partout, et surtout pas devant les images. J'ai opté pour une astuce qui cache l'icône derrière l'image.

a img {
	margin-left: -16px;
	vertical-align: bottom;
}

J'applique une marge négative de même taille que l'icône si l'image est dans un lien. Le vertical-align, c'est pour pas que ca déborde en bas. L'astuce ne marche plus sur une image avec de la transparence et si l'image n'est pas au début du lien. C'est acceptable je trouve.

Lien dans un titre

Il y a un autre endroit où je n'ai pas envie de voir des icônes, c'est dans les titres. Je ne sais pas d'où ça vient, mais il y a comme une sorte priorité sur les lien. Si j'essaye de faire ça, il ne se passe rien :

h1 a {
	background-image: none;
	padding-left: 0;
}

Et dans la documentation, j'ai trouvé un truc intéressant pour forcer le style :

h1 a {
	background-image: none !important;
	padding-left: 0 !important;
}

Bonus

Au départ, j'ai aussi parlé d'indiquer la langue. En général, on va chercher cette information dans l'attribut hreflang comme ceci :

a[hreflang]:after {
	content: "\0000a0[" attr(hreflang) "]";
}

Grâce à ce sélecteur, après le lien, on affiche le contenu du hreflang entre crochets. Ce que vous voyez avant, le \0000a0, c'est le code d'un espace insécable je crois (j'avoue que je me suis contenter de copier ce code :) ).

Conclusion

En découvrant tout ca, ca donne des idées. On en a encore plus quand on voit ca. Le seul truc qui me dérange, c'est l'histoire de la marge négative appliquée à l'image et même en regardant la documentation actuelle du CSS3, je ne vois pas de solution pour sélectionner un parent, en tout cas je n'ai pas trouvé.

Commentaires

5. Le vendredi, février 17 2006, 01:46 par klee

ouais c un bon résumé.

pour les images il est peut etre possible (j'ai pas tester encore)

de décaler l'image vers l'extérieure
plutôt que l'intérieur du lien
avec un overflow:hidden;

je m'en vais vérifier de ce pas ^^

8. Le lundi, février 20 2006, 09:48 par qwix

Kikoo :)
Billet intéressant, cependant (et corrigez moi si je me trompe hein ;) ) il me semble avoir lu quelque part que, si on veut respecter HTTP strictement, les liens relatifs devraient être bannis, au profit de liens absolus, même pour un lien interne, ce qui rend plus difficile de savoir si un lien et externe ou interne.

Du coup, la solution idéale viendrait, comme tu l'as précisé, de la détection totale du nom de domaine afin d'identifier un lien interne/externe.

J'espère que j'ai été compréhensible :/

:)

9. Le lundi, février 20 2006, 11:24 par neolao

Je cherche un peu, je trouve pas de documentation. J'ai regardé quelques exemples sur les liens dans la doc de la W3C du XHTML2, il y a des url en relatif mais rien qui parle explicitement du relatif ou absolu. Donc je sais pas.

11. Le mardi, avril 18 2006, 20:23 par Julien

Puisque ce blog semble être sous dotclear, je me permets de faire partager la manière dont je m'y suis pris pour que les liens ne soient pris en compte que dans mes billets (sinon, entre autres, l'icone "lien externe" apparaît pour les notes, pour le numéro des commentaires, dans les liens qui se trouvent dans le footer, dans ceux de la sidebar, etc... etc..., ce qui n'est pas forcément génial) J'ai procédé de la façon suivante :

.post .post-content a {
background-image : url(images/extlink3.gif);
background-position : 0 50%;
background-repeat : no-repeat;
padding-left : 16px;
}

// pour l'icone a coté du lien...

.post-content a[id|="pnote"] {
background-image : none;
padding:0;
}

//pour que l'icone n'apparaisse pas dans les notes (de bas de page) --> a[] permet de spécifier que la chose ne s'applique que dans les liens dont le champ "id" est égal à ce qui est entre []"

.post-content a[id|="rev"] {
background-image : none;
padding:0;
}
//pour que l'icone n'apparaisse pas dans les notes (renvoi dans la page)

.post-content a[rel|="lightbox"] {
background-image : none;
padding:0;
}
//je fais apparaitre mes images en plus grand avec un script pour dotclear (lightbox js) qui fait un effet du meilleur... heu... effet. Cela me permet de ne pas prendre en compte l'icone dans les images qui s'ouvrent de cette manière...

De cette manière, (en passant par .post .post-content) plus besoin de passer par un h1 a{ pour interdire l'icone dans les titres, puisque cela ne s'applique qu'au contenu du billet...



12. Le mercredi, mai 17 2006, 10:40 par Guillaume

Bonjour,

Cette technique m'intéresse énormément et je vais la mettre en place sur mon blog.
Connaissez vous un site sur lequel on peut télécharger des icones pour liens internes et externes.

Merci

La discussion continue ailleurs

1. Le mercredi, février 15 2006, 14:53 par Le blog de Bertrand

Personnaliser les liens avec CSS

Voici un lien très utile pour ceux qui voudraient personnaliser l'aspect des liens dans leurs pages HTML. Il suffit d'un peu de CSS pour matérialiser les types de liens. Des explications à conserver ;-) Au passage il y a la solution pour

URL de rétrolien :