A recent project had a requirement for a rather peculiar navigational device. Regions on a map were required to act as the trigger to display links to various businesses within that region. This needed to be completed without Flash and we wanted it to be as accessible as possible. This article is about how a client-side HTML Image Map was used to produce a compelling and accessible navigation tool.
** For those of you who want to see it before going any further check out this demo, which contains all the source code.
Back when Hamsterdance and Mahir Cagri were famous a HTML Image Map was a useful tool to web designers. Skip forward a decade and they have fallen so far from regular usage that I found myself double checking that they were still in the HTML specification, which of course it is. I was a little surprised to find that it is in the HTML5 specification as well.
The initial problems identified were as follows:-
The bedrock that our solution rests within the HTML, which comes in 2 parts. Firstly the HTML for the link sets which was a straight forward series of UL lists each containing the appropriate links. These lists are then placed within a single containing DIV.
Now for the more interesting part, the map. We were using a map of Britain divided into 9 regions. We required that each region reacted with a very accurate visual hover response so the first step was to create all the related graphics. This comprised of a single background image of all of Britain showing all the regions in there normal state. Using the same image dimensions a separate image for each region was created displaying just that region in its hover state, with the remainder of the image transparent. By using the same image dimensions it great simplifies the positioning of the region hover state images without adversely affecting performance. The final image was a single transparent pixel, more on that later.
The next step was to create the HTML image map itself. The trick here was to plot the boundary lines between each region accurately enough that the map was properly responsive while not being overly taxing on the development process. After a few false starts Adobe ImageReady was found to be the best tool for the job. It gave the required level of accuracy and the best visual interface for plotting all the boundary points. With all the areas plotted the simple export facility delivered nice, clean HTML. Adding meaningful ALT descriptions on all the MAP AREA hot-spots mustn’t be forgotten.
With our graphics and the HTML Image Map prepared all that remained was to complete the basic structure. This meant putting the Image Map and all an IMG tag for the other graphics into a separate containing DIV.
This revolves around 3 properties in particular: position, display & z-index.
Position absolute for each off the Region hover state images and the the full Britain map. Position absolute for each of the link lists. Position relative on the image map and the containing DIVs. Applying Position to all of the components is essential for Z-index to behave properly.
Display set to none/inline on the region hover state images so that they can be shown at the moment when the users cursor triggers the related regions hover state.
Z-Index is essential so that we can properly stack all these graphics in an order such that the Image Map can do its job, the region hover states can be presented and that the full Britain map gives the user intuitive reference on how to use the navigation.

This is the glue that brings elegance to the solution and functional response to the users interaction. Rather than using the HOVER event MOUSEOVER/MOUSEOUT removes the need for the client to respond only as each region is entered or exited, this is one part of the solution to a dither problem.
By adopting a consistently naming convention for the MAP AREAs, Region hover state images and the Region link lists we can greatly simplify the event handling. Simply extracting the class from the active AREA and appending ‘-map’ or ‘-list’ to trigger the related components.
The final piece of the puzzle was to bridge the gap between a list of links and the fact that they vanish as soon as the users cursor is removed from the MAP region. Adding a CLICK event on the Image Map which inserts ’selected’ to the regions class provided the necessary hook to ensure the required persistent behavior.
An unexpected result of using jQuery to trigger the presentation of the region hover state images was that it gave rise to an unsightly dither of the hover state. By using the MOUSEOVER/MOUSEOUT was one part of the solution, as already mentioned. The second, and key, part of the solution was the positioning of the transparent layer over the top of the map and attaching the image map to it. This meant that there was an constant layer from which the image map could trigger events in an uninterrupted manner.
Acknowledgements
Sitepoint for their HTML & CSS browser compatibility reference.
Smashing Magazines typically comprehensive article on Z-Index.
Gabriel Svennerberg for the cunning transparent layer Image Map dither solution.
Update (2010/1/27)
I nearly came unstuck with this Image Map due to IE not co-operating when I put a drop-down menu on the same page. This article from Brenelz Web Solutions saved the day.
50 Comments
Matt January 24, 2010 @ 10:11 am
Stand up job!
Thank you for the post. I will be using this for a django cms 2 plugin ..
Ian January 25, 2010 @ 2:37 am
@Matt great stuff, when you get the plugin built don’t forget to send us over a link.
dasanco January 29, 2010 @ 11:45 pm
Curious, since you’ve played with this a bit … does it seem as if you might be able to do multiple map layers as well?
In other words could you show a underlying region and an overlying city district at the same time. Where the different cities would change while the underlying region was displayed.
Maybe even on a world map, perhaps three layers. With the lowest being the country.
Jon B February 2, 2010 @ 11:41 am
This is just what I was after – very nice.
Unfortunately, it doesn’t seem to work properly in the horror that is IE6. Any ideas?
Cheers,
Jon
Ian February 3, 2010 @ 6:40 am
The map and the lists are each contained in their own DIV, floated left to bring them side by side. I had failed to add a position:relative to both of these DIV’s hence the crazy behavior. I have double checked this fix in IE6, IE7, FF3.5 and Chrome 1 (all in Windows XP), as well as Safari 4 on Mac. It now behaves as expected in all these browsers.
Patrick Dubinski February 4, 2010 @ 4:54 am
Just what I was looking for! To bad area-maps can’t just be added with a background-color or anything – it would solve so many problems.
I’m definitely going to use this on my site.
tibbley February 16, 2010 @ 3:06 pm
great work, thanks!
Paul February 20, 2010 @ 12:36 pm
good idea i hadn`t even considered the z index for a base transparent layer…
Charles Xavier March 25, 2010 @ 11:17 am
is there way to have one item with content “selected” when the page 1st renders, sort of as a default?
johansrk March 31, 2010 @ 3:32 pm
amazing.. thanks..
consider removing
#map-container {float:left}. Then the map will also work in IE6.
johansrk March 31, 2010 @ 3:37 pm
ups.. didn’t see your comment. Yeah It’s also possible to add the position:relative to the #map-container
Ian April 1, 2010 @ 8:14 am
@Charles Xavier: if you add something like the following immediately after the document.ready declaration you will create a default…
jQuery(‘.midlands-map’).addClass(’selected’).css(‘visibility’, ‘visible’);
jQuery(.midlands-list).addClass(’selected’).css(‘visibility’, ‘visible’);
John April 13, 2010 @ 11:53 am
this is so awesome. just one question…is there an easy way to have the map mouseover return to it’s original state AFTER a link is clicked and followed?
Essentially, user follows a link to another site (using _blank) and when returning to the map tab the map is in the default state.
Thanks!
john April 13, 2010 @ 3:23 pm
ahh…i see what my issue is but i’m still not exactly sure how to fix it.
i don’t require the ‘click and hold’ functionality. so if you click London, it holds the mouseover so that you can select from the list. i don’t require the list, so i’m wondering how to do more of a simple mouseover and mouseout.
thanks.
Ian June 4, 2010 @ 8:23 am
@John – From what I gather you are looking to remove the Click & Hold, leaving just the mouseover. The issue with this is that there is no way to make your region selection persistent such that you can select an option from the related option list.
Case in point – Using a mouseover event only would leave the London region in the situation where it couldn’t be selected. The problem being that you would have to mouseover at least one other region before your mouse pointer could get near the option list. Perhaps the particular implementation you have in mind negates this problem but without more info. I can’t help.
John McC June 15, 2010 @ 3:53 pm
Brilliant work. Looking forward to modifying it for my needs tomorrow.
Rob June 17, 2010 @ 3:50 pm
brilliant… just what i needed. thanks.
Clayton July 2, 2010 @ 4:38 pm
You could have optionally used maphilight for a simpler approach, correct?
http://davidlynch.org/js/maphilight/docs/demo_usa.html
Ian July 5, 2010 @ 2:36 am
@Clayton – I did review jQuery MapHighlight but found it lacking. Looking at the MapHighlight demo of the USA states, when hovering over Michigan or Hawaii only the individual sections highlight rather than the entire collective territory. For what I needed this was a critically lacking. That said in a situation where this isn’t an issue or a necessity it does offer a quicker solution.
JD July 8, 2010 @ 7:48 am
I’m new at implementing JQuery but I have successfully implemented jquery plugins before. I like the additional functionality that this provides. I want to use this plugin for the US map but I noticed that when I change the id and class names for the image map and images, it no longer works properly for me. I’m sure it’s my lack of knowledge, but I can’t find the “hooks” to make these adjustments w/o breaking it. Thank you for your work!
JD July 8, 2010 @ 8:22 am
Okay, not sure how I did it, but it works now. I wish I could delete my posts. Thanks again!
Ian July 8, 2010 @ 9:40 am
No harm done. Besides, trial and error is the best way to properly learn
medani July 14, 2010 @ 1:33 am
Great Jquery Plugin! Brilliant Work.
Rick July 25, 2010 @ 12:42 am
Thank you for posting this… this is great and shows me exactly how to do what I am trying to do.. I wish this came up more in search results than the fairly useless (IMO.. at the least, very poorly documented) jquery maphilight plugin
Sara August 18, 2010 @ 11:27 pm
Thank you so much for the tutorial. But I came across a problem when I trying to add sound clips to the map. I can’t express how much I appreciate if you can shed some lights on a newbie to jquery.
The result that I want: when you click/over the “Scotland” block, it says “Scotland”, click “north west”, it says “North west”. I know it should be easy with the help jquery. But somehow I failed. Aaargh!!!!
What I did:
Midlands & East Anglia
var regionList = ‘.’+$(this).attr(‘id’)+’-list’;
var regionSound = ‘.’+$(this).attr(‘id’)+’-sound’;
jQuery(regionSound).play(); jQuery(regionMap).css(‘display’, ‘inline’);
a variety to search which has according id.
Is there something wrong? To be frank, it crashes my heart to learn jquery.
sara August 18, 2010 @ 11:36 pm
oops, something in the line of “Midlands” is missing. Is it because I just past the code into the comment?
Anyway, I just add html5 audio tag under the h4 title of ul class=”midlands-list”.
the audio has src=”midlands.aif”, id=”midlands-sound” controls=”controls”
so when I click the area, the detail list shows. I can click the audio, it plays well. But when I want it to click-&-play, the script doesn’t work.
Sorry for such long question.
Pete August 24, 2010 @ 11:21 am
Ian,
nice bit of code you put together. I was looking to combine it with jQuery cycle plugin. The plugin prints out a class of “active” depending on what slide is shown. I got the active state to print on the area tag, but I’m having trouble with your code to make the underlying image display. It displays fine with the mouse over, and mouse out functions, but need this one extra event.
thanks again.
-Pete
sara August 29, 2010 @ 8:52 pm
Hi Ian, I’m sorry I haven’t checked my email for a couple days. You are sooo kind and nice. After calming myself down a couple days, I managed to make the sound effect work, and a tooltip function as a plus. Problem solved! It’s so simple that I even wanna punch myself a little bit for being so stupid. LOL. I’m just too eager to get things down by skipping the basic jquery knowledge. What did I learned? — You have to learn walk before you run.
Anyway even the smallest success gives me enough courage to learn jquery. Thank you, thank you, and thank you and all the guys who love helping others.
Bill Bardon October 15, 2010 @ 8:44 pm
Have to say, thanks very much for making this technique and your code available. I’ve put it to use in a location map for a property company, here: http://www.byronreedcompany.com/communities/locations.html.
mark December 12, 2010 @ 12:05 am
I love JQUERY, this is what I am looking for, great tutorial and great JOB! This could help lots of begginers and learners.
Riba January 22, 2011 @ 3:15 pm
Hello Ian – this is excellent. I wanted to create a map of Croatia with clickable regions, and I wanted to avoid flash at all costs. I also wanted the hover effect of course. Your method worked wonderfully apart from the fact that I had to draw manually the imagemap of all 21 (!) Croatian regions.
At the moment it can be seen at work here:
http://www.locusto.com/Po-upanijama,category,1889,parent_id,categories
However it turns out I won’t be using it so I just wanted to let your vistors know they can download the imagemap and graphics here and use it as they see fit:
http://www.locusto.com/Croatia_Imagemap.zip
I know there probably isn’t a huge number of people who might be needing it, but I did invest quite a bit of time to create it and I hate to see it go to waste.
Thanks!
Ian January 25, 2011 @ 3:25 am
Thank you for leaving this feedback. I can appreciate how the ImageMap can be painstaking to create but this is the cost for not using Flash. The work you have done for your Crotian map is excellent and I applaud you for sharing.
James January 30, 2011 @ 12:30 am
Would it be possible to have an initially selected item?
James January 30, 2011 @ 2:44 pm
Nevermind. I figured it out
James January 30, 2011 @ 2:47 pm
Putting this on pages that scroll causes the page to jump. Is there anyway to make it so that the page doesn’t jump to the top of this widget when a link is clicked?
Ric March 3, 2011 @ 8:59 am
Ian, GREAT work. I thought I was going to be SOL when it came to using an image map. You’re my hero, LOL.
Ric
plong0 March 13, 2011 @ 3:09 am
Excellent work Ian!
Thank you so much for sharing your clever solution with us.
Ian March 17, 2011 @ 9:31 am
Hi,
Great tutorial and I’ve almost got it working. However, when I mouse over an area in my map it flashes rapidly whenever I move the mouse – looks horrible.
I used Dreamweaver CS5 to create the map hotsposts. There is only 1 territory on the map with the functionality added yet – Australasia – if you move your mouse over it you’ll see what I mean.
Here is a link to the page http://www.ycdevelopment.co.uk/yc-site/image-map-highlight.php
Vladimir April 6, 2011 @ 1:18 pm
Thank you so much for the example. Simple and reliable. NO FLASH it’s great.
Steve April 8, 2011 @ 6:12 am
Thanks for sharing – nice work.
admin April 8, 2011 @ 6:23 am
@Ian: The rapid flash is most likely due to the image map being on the layer you are fading in&out. Instead it should be on an invisible layer overlaying the graphics. Most likely, check the final section of the article, this same issue had me snaked for a while as well…
Chris April 11, 2011 @ 2:21 pm
Would it be possible to disable the hover state in favor of just a click to make things easier for an ipad/iphone user?
Elvin Xhimitiku April 20, 2011 @ 3:49 am
You are officially an html BAD ASS!!! Great post and good use of the html image map
Cheers mate
Thyx May 3, 2011 @ 12:50 am
simple et effective !
thanks for this great piece of code
admin May 3, 2011 @ 2:12 am
@Lisa: I used Dreamweaver, which worked pretty well. No free alternative comes to mind unfortunately.
admin May 3, 2011 @ 2:14 am
@Chris: Just remove the entire …moveover/…mouseout section of the jQuery.
Nathaniel May 5, 2011 @ 7:05 am
I am basing a Joomla component off what you’ve done here. Thanks for the help.
John Pitchers May 27, 2011 @ 7:34 am
Hi Ian, thx for the code and explanations. With a little JQuery fading I was able to use your code to create the image map on this page. http://bit.ly/jsPhe7 Works a treat.
Steven July 19, 2011 @ 4:24 am
Thanks a lot for this. I was looking for a solution without using Flash and this was spot on
Steven August 8, 2011 @ 3:48 am
is it possible to use the same script twice on a single page? I have two different diagrams with 2 separate map areas. They need to run independently from each other. Thanks.
Comment on this Post