L'idée

Image non disponible
Voir une démo

Voir une démo en ligne.

Il y a quelque temps, j'ai dû mettre en place une image avec des zones réactives et des infobulles. J'ai remarqué celles du site de Firefox que j'ai trouvées plaisantes et je m'en suis inspiré pour créer les miennes.

Le but principal est d'obtenir un code facile à utiliser et à maintenir, sans avoir besoin de connaissances particulières en programmation.

Comme vous le verrez, vous n'avez pas besoin d'aptitudes particulières en développement pour mettre en place les repères et les infobulles. Il suffit de placer une balise <div> dans votre page avec deux attributs HTML5 personnalisés pour la positionner. Je pense que c'est suffisamment simple.

Les attributs HTML5 data et jQuery

HTML5 propose une fonctionnalité très pratique, les « attributs data personnalisés », qui permettent de stocker des valeurs spécifiques afin de faciliter l'écriture du code JavaScript. Ainsi, plus besoin d'utiliser les attributs rel ou title destinés à une utilisation en JavaScript.

Voici comment les utiliser :

 
Sélectionnez

<div data-foo="bar"></div>

et voici comment les exploiter à l'aide de jQuery :

 
Sélectionnez

var test = $('div').data('foo');

Dans cet article, nous utiliserons ces attributs pour stocker les coordonnées des repères pour notre carte.

Pour en savoir plus sur les attributs HTML5 data, vous pouvez regarder ces liens :

Le HTML

 
Sélectionnez

<div id="wrapper">
   <img width="920" height="450" src="world-map.jpg" alt="Continents">   
   <div class="pin pin-down" data-xpos="450" data-ypos="110">      
      <h2>Europe</h2>      
      <ul>
        <li><b>Superficie (km²) :</b> 10,180,000</li>
        <li><b>Population :</b> 731,000,000 </li>
      </ul>
   </div>
</div>
  • #wrapper - C'est l'élément qui englobe tous les autres. Sa propriété CSS position est relative et je pense que vous savez pourquoi.
  • img - L'image qui servira « d'image de fond ».
  • .pin - Cet élément positionné en absolute contient le repère et le contenu de l'infobulle qui sera affiché sur l'événement mouseenter. De plus, la classe CSS pin down précise la direction du repère.
  • data-xpos="450" data-ypos="110" - Les attributs personnalisés qui vous permettent de spécifier les positions X (de droite à gauche) et Y (du haut vers le bas) en pixels pour positionner les différents repères. Dans cet exemple, le repère sera placé à 450px à gauche et 110px du haut.

Le CSS

Il n'y a pas grand chose à expliquer ici, je pense que le code est suffisamment facile à comprendre :

 
Sélectionnez

/* Positionnement relatif */
#wrapper {
    position: relative;
    margin: 50px auto 20px auto;
    border: 1px solid #fafafa;
    -moz-box-shadow: 0 3px 3px rgba(0,0,0,.5);
    -webkit-box-shadow: 0 3px 3px rgba(0,0,0,.5);
    box-shadow: 0 3px 3px rgba(0,0,0,.5);
}

/* Masquer les infobulles */
.pin {
    display: none;
}

/* Styles des infobulles et des repères */
.tooltip-up, .tooltip-down {
    position: absolute;
    background: url(http://www.red-team-design.com/wp-content/uploads/2011/10/arrow-up-down.png);
    width: 36px;
    height: 52px;
}

.tooltip-down {
    background-position: 0 -52px;
}

.tooltip {
    display: none;
    width: 200px;
    cursor: help;
    text-shadow: 0 1px 0 #fff;
    position: absolute;
    top: 10px;
    left: 50%;
    z-index: 999;
    margin-left: -115px;
    padding:15px;
    color: #222;
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
    border-radius: 5px;
    -moz-box-shadow: 0 3px 0 rgba(0,0,0,.7);
    -webkit-box-shadow: 0 3px 0 rgba(0,0,0,.7);
    box-shadow: 0 3px 0 rgba(0,0,0,.7);
    background: #fff1d3;
    background: -webkit-gradient(linear, left top, left bottom, from(#fff1d3), to(#ffdb90));
    background: -webkit-linear-gradient(top, #fff1d3, #ffdb90);
    background: -moz-linear-gradient(top, #fff1d3, #ffdb90);
    background: -ms-linear-gradient(top, #fff1d3, #ffdb90);
    background: -o-linear-gradient(top, #fff1d3, #ffdb90);
    background: linear-gradient(top, #fff1d3, #ffdb90);
}

.tooltip::after {
    content: '';
    position: absolute;
    top: -10px;
    left: 50%;
    margin-left: -10px;
    border-bottom: 10px solid #fff1d3;
    border-left: 10px solid transparent;
    border-right :10px solid transparent;
}

.tooltip-down .tooltip {
    bottom: 12px;
    top: auto;
}

.tooltip-down .tooltip::after {
    bottom: -10px;
    top: auto;
    border-bottom: 0;
    border-top: 10px solid #ffdb90;
}

.tooltip h2 {
    font: bold 1.3em 'Trebuchet MS', Tahoma, Arial;
    margin: 0 0 10px;
}

.tooltip ul {
    margin: 0;
    padding: 0;
    list-style: none;
}

Le jQuery

Voici le code jQuery qui va s'exécuter une fois la page chargée :

 
Sélectionnez

$(document).ready(function(){

    // Définir les dimensions du conteneur pour s'adapter à la taille de l'image
    $('#wrapper').css({'width':$('#wrapper img').width(),
                      'height':$('#wrapper img').height()
    });

    // Sens de l'infobulle
    var tooltipDirection;
                 
    for (i=0; i<$(".pin").length; i++)
    {
        // Définir le sens de l'infobulle - haut ou bas
        if ($(".pin").eq(i).hasClass('pin-down')) {
            tooltipDirection = 'tooltip-down';
        } else {
            tooltipDirection = 'tooltip-up';
            }

        // Insérer l'infobulle
        $("#wrapper").append("<div style='left:"+$(".pin")
            .eq(i).data('xpos')+"px;top:"+$(".pin")
            .eq(i).data('ypos')+"px' class='" + tooltipDirection +"'>\
                    <div class='tooltip'>" + $(".pin").eq(i).html() + "</div>\
                </div>");
    }    

    // Afficher / masquer l'infobulle
    $('.tooltip-up, .tooltip-down').mouseenter(function(){
                $(this).children('.tooltip').fadeIn(100);
            }).mouseleave(function(){
                $(this).children('.tooltip').fadeOut(100);
            });
});

Voir une démo en ligne.

Comment cela fonctionne et comment l'utiliser

Cet exemple fonctionne aussi sur les navigateurs anciens comme IE6, mais les fonctionnalités CSS3 comme les dégradés ou les ombres ne seront bien entendu pas disponibles.

  1. Placez votre image (dans l'élément <div id="wrapper">) sur laquelle vous voulez placer vos repères.
  2. Ajoutez le contenu que vous souhaitez afficher dans les infobulles dans <div class="pin" data-xpos="450" data-ypos="110">.
  3. À partir de là, jQuery se charge du reste :
    1. le conteneur adapte ses dimensions à celles de l'image ;
    2. le contenu des infobulles est masqué en CSS à l'origine et ajouté au contenu initial ;
    3. les repères et infobulles sont positionnés sur l'image en fonction des valeurs des attributs personnalisés HTML5 ;
    4. en utilisant mouseenter et mouseleave, les infobulles sont affichées ou masquées.

Conclusion et remerciements

J'espère que vous avez apprécié cet article. N'hésitez pas à poster des commentaires (y compris sur le site de l'auteur) si vous avez des suggestions à proposer.

Cet article a été publié avec l'aimable autorisation de Catalin Rosu. L'article original peut être lu sur le site de Red Team Design : Image map with CSS3 & jQuery tooltips.

Nous tenons aussi à remercier f-leb pour sa relecture attentive de cet article.