Tooltips can play a big role in your web designs and that isn’t new anymore. Just use them correctly and they will help you improve user experience.
We have seen before how to create some good looking CSS3 tooltips and today you’ll learn how to create an image map with pins and tooltips.

The idea
A while ago, I had to create an image map with tooltips and, being inspired by some cool tooltips I noticed on Firefox’s website, I decided to create these ones.
The principal purpose was to have something that is easy to use and update, without needing any developing knowledge.
As you will see further, you won’t need any developer skills to add pins with tooltips to an image. You’ll just need to add a div with your content and set two HTML5 custom attributes for positioning it. I’d say is simple enough.
HTML5 data attributes and jQuery
HTML5 has a cool feature named “custom data attributes”, which can help you store arbitrary snippets of metadata for the purpose of making your Javascript code simpler. So, the thing is that now you can avoid using attributes like rel or title for Javascript purposes.
Here’s how the syntax looks:
<div data-foo="bar"></div>
and this is how you can get the above value with jQuery:
var test = $('div').data('foo');
In this article, we’ll use these attributes to store data like positioning coordinates for our map pins.
Want to read more about HTML5 custom data attributes? Then check the following resources:
The HTML
<div id="wrapper"> <img width="920" height="450" src="world-map.jpg" alt="World continents"> <div class="pin pin-down" data-xpos="450" data-ypos="110"> <h2>Europe</h2> <ul> <li><b>Area (km²):</b> 10,180,000</li> <li><b>Population:</b> 731,000,000 </li> </ul> </div> </div>
#wrapper– This is the element that wraps all the other elements. Itspositionvalue isrelativeand I bet you guess why’s that.img– the image that will behave as “background”..pin– Thisabsolutepositioned element contains the pin and also the tooltip content which will be displayed on mouseenter event. Additionally, thepin-downclass specify the pin type.data-xpos="450" data-ypos="110"– HTML5 custom attributes that help you specify the X (left to right) and Y (top to bottom) axis values (px) for positioning the respective map pin. In this example, the pin will be positioned 450px from left to right and 110px from top to bottom.
The CSS
There’s no much to explain here, I think the following lines are quite easy to understand:
/* Relative positioning*/
#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);
}
/* Hide the original tooltips contents */
.pin {
display: none;
}
/* Begin styling the tooltips and pins */
.tooltip-up, .tooltip-down {
position: absolute;
background: url(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;
}
The jQuery
Below you can find the jQuery code that will execute when the page loads:
$(document).ready(function(){
// set the wrapper width and height to match the img size
$('#wrapper').css({'width':$('#wrapper img').width(),
'height':$('#wrapper img').height()
})
//tooltip direction
var tooltipDirection;
for (i=0; i<$(".pin").length; i++)
{
// set tooltip direction type - up or down
if ($(".pin").eq(i).hasClass('pin-down')) {
tooltipDirection = 'tooltip-down';
} else {
tooltipDirection = 'tooltip-up';
}
// append the tooltip
$("#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>");
}
// show/hide the tooltip
$('.tooltip-up, .tooltip-down').mouseenter(function(){
$(this).children('.tooltip').fadeIn(100);
}).mouseleave(function(){
$(this).children('.tooltip').fadeOut(100);
})
});
How it works and how to use it
This is an example that works even on older browsers like IE6, though CSS3 features like gradients and shadows won't be available of course.
- Set the image (within
<div id="wrapper">element) you wish to add pins for. - Add the content you need to displayed as a pin with tooltip in
<div class="pin" data-xpos="450" data-ypos="110"> - From now on, the jQuery will do the rest:
- Based on the image dimension, the relative wrapper inherits the img's width and height.
- The initial content you added will be hidden (this is done via CSS) and new elements will be appended based on initial content.
- Also, the appended pins and tooltips will be positioned using the coordinates you added as HTML5 data attributes.
- Then, using
mouseenterandmouseleaveevents, the tooltips are displayed/hidden.
That's all!
I hope you enjoyed this tutorial and feel free to comment if you have any suggestion. Thanks for reading!
That’s pretty sweet Red. Would be perfect for a travel site.
Thanks Lloyd, I’m glad you like it.
nice tooltip
Or an about us page with a group of staff members – you could use the tabs to put names to faces.
Great work BTW ;)
Thanks Andrew! :)
Hey thanks for the article Red. Just one question… what is the benefit of defining the array inside the for loop?
for (i=0; i<$(".pin").length; i++)
{
// store initial tooltips contents within an array
var tooltipContent = new Array();
tooltipContent[i] = $(".pin").eq(i).html();
…
Isn't this preferrable?
var tooltipContent = new Array();
for (i=0; i<$(".pin").length; i++)
{
// store initial tooltips contents within an array
tooltipContent[i] = $(".pin").eq(i).html();
…
Same thing for the tooltipDirection…
Mat, of course, it’s not good to define an array or a variable inside a loop.
Actually, the
tooltipContentarray andtooltipDirectionvariable aren’t used outside the loop and they are quite redundant here.Thanks for the heads up, when I’ll have some time I’ll update the jQuery code above.
I’ve just updated the jQuery code for this tutorial.
Hi Red,
I offer my Deepest Gratitude To you for creating cool CSS3 tooltips and sharing it with us.
I posted about you in my Gratitude Blog where I show my Gratitude To all of them for whom I’m grateful.
And again I tweeted about your good work.
Thanks Jimmy, I’m glad you liked it.
odd why cant i see the initial pins when there is no mouse over when i saved it locally?
hmm figured it out you set an image as background
background: url(/wp-content/uploads/2011/10/arrow-up-down.png
How is ie 7 and 8 support? Love the easyness great job!
This is a cross browser solution, so you shouldn’t worry about it! ;)
I am having a little hiccup with IE7′s z-index. One of my tooltip’s keeps going behind the other pins. Seems to be depend on the order of pins in my html file. Really weird.
Found a quick fix. Added the following css for IE7 stylesheet:
.tooltip-up:hover {
z-index: 1000;
}
.tooltip-down:hover {
z-index: 1000;
}
Nice, but doesn’t work when you change the wrapper id. For example, if I have #wrapper already on my page (for footer push in css etc), I would have to change this id through out my site, or leave this.
When I change the #wrapper in this tutorial to say, #map_wrapper or anything else, the whole thing breaks. Of course I also change the css and js references, but it appears you must use #wrapper in order for this to work.
Is there a reason for this?
Cheers :)
Dave, It works: http://jsfiddle.net/catalinred/74AqW/ ;)
Notice the
#map-wrapperinstead#wrapper.Cheers Red, very odd, when I tested this locally with the name changes it didn’t work, but clearly does in your example link.
Must have been something my end, sorry!
Thanks for the follow up though :)
How do I open a div which contains a set of images?
This div should be linked in each tool tip text. like for each country i need to show some set of images.
Hi Red,
I LOVE YOU. Your efforts are really incredible and have lot of guideline for those whom don’t know more about CSS and HTML as well as other online tools you linked.
Please tell me how I can compatible my CSS3 and HTML5 code for all browsers.
Thanks!
Regards,
Hi Red,
Thanks for the fantastic tooltip plugin! I have one quick question… I am trying to implement a fancybox modal overlay when users click a link that lives inside my tooltips. For some reason the modal window will not function when the link lives inside my tooltips (I have tested on the same page with links outside the tooltip and they work.) Any idea why this might be happening or thoughts on how I can get everything working?
Thanks,
Andrew
Hi Andrew, I’m not sure…
Just make sure you don’t have any JavaScript errors in that page. If you’re using Firebug on a Windows, hit CTRL+SHIFT+J and take a look.
Hey Red,
Thanks for your response. I have tried debugging the javascrip errors on the page with no luck. I stripped all of the content out of my page except for the map with tooltips and the modal content. Below is a link to that page.
http://karshhagan.com/testing/map_test.html
As you can see, the modal window appears when you click the text link below the map, but not when you click the link inside of my tooltip on the map. I have tried using jsfiddle to help debug the problem but have had no luck there either. Any way you could take a look and see if you notice any glaring issues?
Thanks again,
Andrew
Got it all figured out. Thanks again for the great plugin!
Hi Red,
This is brilliant! One question, how can I change the ‘+’ (pin before it is moused over) to show say, a country name???
Thanks!
Hi Adam, thank you and I’m glad you like it.
Regarding your question, technically, you could to that by extracting the
h2from each, and then display it when appending the tooltip.I guess you know that, in this case, the pins images would need to change (increase by width), as they should be able to contain the country name for example.
Thanks for the reply Red,
I understand what needs to be done but actually making it work is another thing!
Any ideas? Forgive me I am a noob.
The pin could simply be a div with text inside that when moused over, reveals the tooltip.
Thanks for your help Red.
Adam, here’s a working example for you: http://jsfiddle.net/kdrdP/1/
All you need to to further is to update the original “arrow-up-down.png” by increasing width and removing the “+” signs. Remove the “wheat background-color” I temporarily added.
Hope that helps!
That’s brilliant Red thank you ever so much for your help with this! :D
Click the following link to view my result! A touch of css and photoshop works wonders! – http://www.vapor-trail.co.uk/img_map_names/names.html
One more question and I will finally leave you alone Red ;)…
How would I create a different image for each location? Image dimensions will stay the same, I simply want to change the colour for each location.
Thanks again Red you are a life saver!
I too am looking for a solution for this. Instead of colors, I am trying to swap the “arrow-up-down.png” file depending on location. I tried adding a div tag outside with a different id (or class) to call out a different png file. Instead, I get nothing to show but the tooltip’s popup still works.
Example:
.tooltip-up, .tooltip-down {
position: absolute;
width: 36px;
height: 25px;
}
#unitedstates .tooltip-up, #unitedstates.tooltip-down {
background: url(images/arrow-usa.png) no-repeat top left;
}
TEXT
i tested a page that works but i moved it to the wordpress.. up and down did not show up that is something missing!
background: url(/wp-content/uploads/2011/10/arrow-up-down.png in map-style.css
but now working.
I SOLVED IT!!! Thank you for your clickable map.. :)
Aju, I am glad you fixed it. ;)
Thanks Red. You’re doing a wonderful service. Whether you know it or not (or even believe it) – you are serving God by providing this incredibly generous service. Bible teachers like myself are learning from you so we can make our theology websites far more effective. Thank you so much, and God bless you.
I like this. Thanks!
Pete, I’m just trying to do my best. Your words are far too kind. Thanks for your comment.
Red, solution is very clear and easy to implement on our personal project. Actually we don`t use map as background. One picture taken from helicopter in birds perspective is our map of interest/dolphin tracking. Now we need to set marks for exact location where we saw dolphins and that works. We used your solution for local project in our Association and it will be recorded for presentations in our office.
Our problem is that we try to implement popup engine to open specific link from popup content. We found http://www.pirolab.it/pirobox/ good and lightweight as solution but it seems that image is opened in new window what is wrong.
Maybe you can help us to make it work. What part of code we need to add to your script to make it work. Or you have better solution for popup.
Thanks in advance
Marko
Hi Red,
please can you answer. thanks
Hi Marko, sorry for my late reply but I’m afraid I’m not able to help you with your problem.
To avoid wasting time by merging two different solutions , I’d recommend you to find a solution that fully fit your needs.
No problem Red,
thanks on your effort.
Keep the good work.
Cheers
support bootstrap twitter?????????
where is Caspian Sea in your map?!
Hm, for some reason is just not there :)
what reason?
but it not works in IE 8
Yes, it works.
I worked this code out to use my own map and change things to work fine for my site, but one thing I am still trying to make work is the use on ipad. The different screen sizes mess up the coordinates, but there should be a resizing addition to the code I would think, but I just can’t figure it out. Any suggestions?
Just a few browser differences I found. Chrome will not automatically set the width and height of the image. If you specify the width and height ie Chrome will only pick up the width.
Firefox will automatically detect the width and the height even without setting them on the img tag.
Thanks Red, nice work. Just want to know that if we can put image in the pop ups :-)
got it :-) the normal img tag is working..
For one reason or another my plotted points are showing up in different places on different browsers & computers. Why would this be? Any idea on a fix?
These are the two pages I’m using it on…
http://www.abcchurch.org/outreach/global/
http://www.abcchurch.org/outreach/regional-local/
Very nice!! Thanks!
Any way to make it responsive?? so tool tips scale with the image map.
Saw this, https://github.com/stowball/jQuery-rwdImageMaps
But not sure if it would work with it.
I second this question!
Very nicely done… helpful tips about HTML5…
Thanks a lot…Really appreciate it…
Hi Red,
Is there a way to vary the width of the tooltips? I have over 20 on an image and some need to be 40-50 px wider than the others so text displays correctly. Is it possible to set another class, such as “pin pin-down2″ and create a separate CSS for it? I tried to go through and add another class to the code (and was able to make one tooltip wider than the rest – so I think it might work) but then all of the tool tips went in the same direction “pin”.
Any assistance would be great!
Frank
Hello Red,
Thanks we are using your solution on multiple sites with great effect :)
Just a quick question is there a way we could easily hide/show all pin points on click of a “a href”?
Best regards
Mat
Mat, nice to hear you’re using this for your projects.
Now, considering you’re using one of the latest jQuery versions (as 1.8.3.), you can use something like that:
<a href="#" class="toggle-pins">Toggle map pins</a> <script> (function(){ $('.toggle-pins').on('click', function(){ $('[class*="tooltip-"]').toggle(); }) })() </script>Great work and useful for web developers
Hi guys,
This works great! But, how do I remove the triangle that pops up during the mouse over? I want to get rid of it for my application. It’s that triangle that matches up with the background that I’m talking about when you mouse over.
Hi,
are these tooltips responsive?
@Katarina,
i think that these tooltips are not responsive. Maybe author have some fix for you.
Regards,
Instead of a single x y point for a pin, can you make it a clickable area for each?
Hi Red
This article is very nice It helped me to understand key concepts in tooltip styling
Hi very nice tooltip!!!!! I have just a question if i want different width for each tooltip what can I do?
Thanks
Hi how can I change the bg position for the pins? I need to put people faces in the pins!
http://vejaseuprojeto.com.br/asb/
I’m trying to add a class in the html and set the bg position for that class in css, but it doens’t work!
SOLVED!!!! Thanks for the script, it’s awesome!