Astuces Web - Info-bulles
Présentation
À l'aide de l'attribut title
des balises HTML,
il est possible d'afficher une info-bulle lorsque la souris survole
l'élément.
Exemple
<span title="Voici une info-bulle !">Survolez-moi !</span>
Sympa, non ? Mais, je ne sais pas ce que vous en pensez, mais l'info-bulle
est assez laide quand même... En tout cas, elle l'est dans les vieux
navigateurs :
Bah et alors ! Avec un peu de CSS on doit bien pouvoir régler ça, non ?
Ah si seulement (¬_¬";)... le problème, c'est que cette
info-bulle ne correspond pas à une balise
HTML.
Elle est gérée par le navigateur et il n'est donc pas possible
de modifier son aspect.
Mais ne vous en faites pas. Il existe plein de façon de remédier
à cela. Laissez-moi vous montrer ma façon !
Info-bulles sur mesures
La méthode que je vais vous présenter ici consiste à
écrire et utiliser des fonctions JavaScript qui permettront
d'afficher le texte que bon nous semble lorsque l'on survole un
élément.
Par la suite, nous utiliserons un peu de
CSS afin de
donner un aspect un peu plus présentable à notre info-bulle.
Faire sa bulle
- utiliser une
div
prévue à cet effet ; - créer une nouvelle
div
et l'ajouter à la page.
La première méthode consiste à créer dans la page une zone qui
sera affichée lorsque l'on survole le bon élément. Cela peut être fait
avec du CSS, en jouant avec les états :hover
et, du coup, Ça n'a rien de vraiment intéressant.
En toute logique, je vais donc vous présenter la seconde méthode (^_^).
Pour commencer, on va devoir créer une balise en JavaScript :
var div = document.createElement('div'); div.id = 'tooltip'; div.style.visibility = "hidden"; document.body.appendChild(this.div);
On créé la balise, on lui donne un identifiant, on la cache puis on
l'ajoute au document.
Ensuite, il faut remplir la balise avec le contenu que l'on souhaite
afficher, puis la rendre visible.
div.innerHTML = text; div.style.visibility = "visible"; isVisible = true;
Avec quelques améliorations et en mettant tout ça dans une fonction, on obtient ceci :
var isVisible = false; var div = null; function show(text) { if (isVisible == false) { if (div == null) { // add tooltips to body div = document.createElement('div'); div.id = 'tooltip'; div.style.visibility = "hidden"; document.body.appendChild(div); } // Make tooltips visible and fill with the text div.innerHTML = text; div.style.visibility = "visible"; isVisible = true; } }
Du coup, il faut maintenant faire disparaitre l'info-bulle. Pour cela, rien de bien extraordinaire :
function hide() { if (isVisible == true) { // Hide tooltips if (div != null) { div.style.visibility = "hidden"; // Remove tooltips from body document.body.removeChild(div); div = null; } isVisible = false; } }
On vérifie que l'info-bulle est visible et que la balise existe, on la cache puis on la retire de la page.
Bulles à tête chercheuse
Bien. On sait créer notre info-bulle et la détruire, mais il faudrait pouvoir la positionner au bon endroit. D'ailleurs, si l'info-bulle pouvait suivre la souris, ça pourrait être sympa. Et beh y'a plus qu'â :
function move(e) { if (isVisible) { var div = document.getElementById('tooltip'); if (navigator.appName != "Microsoft Internet Explorer") { div.style.left = e.pageX + 5 + "px"; div.style.top = e.pageY + 10 + "px"; } else { if (document.documentElement.clientWidth > 0) { div.style.left = 20 + e.x + document.documentElement.scrollLeft + "px"; div.style.top = 10 + e.y + document.documentElement.scrollTop + "px"; } else { div.style.left = 20 + e.x + document.body.scrollLeft + "px"; div.style.top = 10 + e.y + document.body.scrollTop + "px"; } } } }
Alors ici, ça peut faire un peur mais il ne faut pas ;)
La fonction effectue juste des tests supplémentaire en fonction du
navigateur (bizarrement, c'est encore Microchiotte qui nous
€$*/&!$...).
Donc, en clair, la fonction va positionner l'info-bulle un peu en dessous
de là où se trouve la souris, en se basant sur les
coordonnées d'origine de l'évènement.
Pour finir, on indique on document d'appeler la fonction lorsque l'on bouge
la souris dans la page :
document.onmousemove = move;
Buller en beauté
Bon, OK. On a notre info-bulle, mais si vous tester tel quel, vous
constaterez qu'il manque quelque chose... l'info-bulle !
Et oui. On a pas définit que la position d'une info-bulle devait
être absolue pour prendre en compte top
et left
(si vous regardez en bas de la page, vous pourrez voir apparaître
l'info-bulle), et on a même paramétré l'affichage !
Du coup, c'est encore plus laid que ce qu'avec title
(¬_¬";)...
Heureusement, le CSS arrive !
Pour empêcher cela, on ajoute la classe de la balise au moment de la création :
div.className = 'tooltips';
Puis on définit une classe CSS correspondant :
.tooltips { max-width:500px; overflow: hidden; position:absolute; border:1px solid #C0C0C0; background:url('bg_tooltip.gif') 100% 100% repeat-x #FFFFFF; padding:8px; font-family:Consolas, Arial, san-serif !important; font-size:11px; color:#80808; }
Bien évidemment, vous êtes libre de modifier l'apparence de votre
info-bulle (je vous recommande tout de même de ne pas trop vous éloigner
de la première partie du CSS).
Pour le fond, j'utilise une image toute bête qui est un dégradé de blanc
vers un gris (très très) pâle. Vous pouvez facilement le reproduire avec
du CSS3 :
.tooltips { background-image: -o-linear-gradient(top, rgb(255, 255, 255) 0%, rgb(240, 240, 240) 100% ); background-image: -moz-linear-gradient(top, rgb(255, 255, 255) 0%, rgb(240, 240, 240) 100% ); background-image: -webkit-linear-gradient(top, rgb(255, 255, 255) 0%, rgb(240, 240, 240) 100% ); background-image: -ms-linear-gradient(top, rgb(255, 255, 255) 0%, rgb(240, 240, 240) 100% ); background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgb(255, 255, 255) ), color-stop(1, rgb(240, 240, 240) ) ); background-image: linear-gradient(top, rgb(255, 255, 255) 0%, rgb(240, 240, 240) 100% ); }
Et pour rendre le tout encore plus agréable, on met des bords arrondis.
.tooltips { -webkit-border-radius: 6px; -moz-border-radius : 6px; border-radius : 6px; }
Code complet
JavaScript
var isVisible = false; var div = null; function show(text) { if (isVisible == false) { if (div == null) { // add tooltips to body div = document.createElement('div'); div.id = 'tooltip'; div.className = 'tooltips'; div.style.visibility = "hidden"; document.body.appendChild(div); } // Make tooltips visible and fill with the text div.innerHTML = text; div.style.visibility = "visible"; isVisible = true; } } function hide() { if (isVisible == true) { // Hide tooltips if (div != null) { div.style.visibility = "hidden"; // Remove tooltips from body document.body.removeChild(div); div = null; } isVisible = false; } } function move(e) { if (isVisible) { var div = document.getElementById('tooltip'); if (navigator.appName != "Microsoft Internet Explorer") { div.style.top = e.pageY + 10 + "px"; div.style.left = e.pageX + 5 + "px"; } else { if (document.documentElement.clientWidth > 0) { div.style.top = 10 + e.y + document.documentElement.scrollTop + "px"; div.style.left = 20 + e.x + document.documentElement.scrollLeft + "px"; } else { div.style.top = 10 + e.y + document.body.scrollTop + "px"; div.style.left = 20 + e.x + document.body.scrollLeft + "px"; } } } } document.onmousemove = move;
CSS
.tooltips { max-width:500px; overflow: hidden; position:absolute; border:1px solid #C0C0C0; background:url('bg_tooltip.gif') 100% 100% repeat-x #FFFFFF; padding:8px; font-family:Consolas, Arial, san-serif !important; font-size:11px; color:#80808; }
CSS3
.tooltips { -webkit-border-radius: 6px; -moz-border-radius : 6px; border-radius : 6px; background-image: -o-linear-gradient(top, rgb(255, 255, 255) 0%, rgb(240, 240, 240) 100% ); background-image: -moz-linear-gradient(top, rgb(255, 255, 255) 0%, rgb(240, 240, 240) 100% ); background-image: -webkit-linear-gradient(top, rgb(255, 255, 255) 0%, rgb(240, 240, 240) 100% ); background-image: -ms-linear-gradient(top, rgb(255, 255, 255) 0%, rgb(240, 240, 240) 100% ); background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgb(255, 255, 255) ), color-stop(1, rgb(240, 240, 240) ) ); background-image: linear-gradient(top, rgb(255, 255, 255) 0%, rgb(240, 240, 240) 100% ); }
Résultat
Utilisation
Survolez-moi !
Une démonstration brute est disponible ici.
Pour aller plus loin
Info-bulle savoyarde
Pour avoir encore plus de confort, il est fréquent de voir apparaitre les info-bulles avec un fondu. Pour cela, on utilise la bibliothèque jQuery et sa fonction fadeIn() :
$('tooltip').css({top: e.pageY+10,left: e.pageX+20}).fadeIn(350);
Encore mieux ?
Du coup, c'est un peu bête car on n'utilise plus l'attribut
title
et on est obligé de définir une classe, l'action quand
la souris rentre et quand elle sort de l'élément à
chaque fois...
Une amélioration classique de ce genre de système est de continuer d'utiliser
title
et d'avoir une fonction qui va parser la page et faire la
transition vers le système présenté jusqu'ici.
Avec jQuery, voilà ce que cela pourrait donner :
$('body [title]').each(function() { var $item = $(this); var $tooltip; // Make sure the item has a title if( $item.attr('title').length>0 ) { var title = this.title; // Empty the title this.title = ''; // Actions to be taken when hovering $item.hover(function(e) { // Build the tooltip and append it to the body $tooltip = $('') .appendTo('body') .hide(); // Append the content to the tooltip $tooltip.html(title); // Set the tooltip position and fade it in $tooltip.css({ top: e.pageY+10, left: e.pageX+20 }) .fadeIn(350); }, function() { // Remove the tooltip $tooltip.remove(); }); // Bind a mouse move function $item.mousemove(function(e) { // Move the tooltip relative to the mouse $tooltip.css({ top: e.pageY+10, left: e.pageX+20 }); }); } });
La démonstration jQuery est disponible ici.
Vous pouvez également télécharger une archive de ma version optimisée ici.
À propos
Ce petit tutoriel a été réalisé en se basant sur mes connaissances personnelles et mon vécu. Je ne prétends pas montrer ici LA solution mais mon approche pour résoudre un «problème» donné.
Les extraits de code sont inclus et mis en forme dans la page à l'aide de Syntax Highlighter. C'est une extension entièrement écrite en JavaScript. Jetez-y un œil ou deux ;)
Vous l'aurez peut-être remarqué, mais toutes les balises
textes que j'ai utilisé et qui avait une info-bulle était
soulignées en pointillé.
Ce n'est pas le fait du navigateur !
C'est une «règle» typographique que l'on retrouve
fréquemment dans les sites Web pour indiquer la présence
d'informations supplémentaire.
abbr, acronym, span[title], strong[title], em[title], label[title], .info { border-bottom:1px dotted #666; /* souligner en pointillé */ cursor: help; /* changer le curseur de la souris */ }
Pour voir une autre méthode pour modifier les info-bulles, vous pouvez aller ici.