Use CSS to build a map with hoverable regions.

Here’s a quick little tip on how to build a map with hoverable regions with a few little CSS tricks.

Before we get into any details, you can check out the working demo here.

 

Building the maps

Once you select an image, you want to create a file with multiple instances of the map. I have trimmed my map down to 542px wide by 592px tall. Since I am going to create a new image that has three instances of this map aligned horizontally, I will triple the width to 1662px. In the left third or the first 542px, I will keep my original map. In the second and third, I am going to create separate instances of the map with my regions highlighted. Here is the master image. You will notice that I have multiple regions highlighted in the second instance of the map. (Doing this will save bandwidth. It will make more sense after we cover the :hover effect)

 

Writing the HTML

The HTML to make this work is very simple. We are a going to create a unordered list with each region as a list item, and each list item will contain a link.

<ul id="map">
	<li class="canada"> <a href="#1"> Canada</a> </li>
	<li class="mexico"> <a href="#3"> Mexico</a> </li>
	<li class="america"> <a href="#2"> United States</a> </li>
</ul>

 

Making it all work with CSS

Below we will set a few styles for the map. The <ul> gets a background image, height, width, margin, padding and position. Then, we go on to remove the bullets from the <li>’s and set their position to absolute. One of the neat little tricks here is setting the <ul>’s position to relative and the <li>’s position to absolute. Later on, when we are going to set up the position of the hoverable areas, this will let us set their position based on the top left point of the <ul>.

#map { width: 542px; height: 592px; background: url(US_Map.jpg); margin: 10px auto; padding: 0;
       position: relative; }
#map li { margin: 0; padding: 0; list-style: none; position: absolute; }
#map li, #map a { display: block; }

Now we need to position the links over the areas that we want to be hoverable. We have assigned a class name to each of the <li>s, so we want to position the tops of those at the top of the areas of their corresponding regions on the map. Next, we are going to set a height and width for the link inside the <li> so that it creates an area that tightly fits over the region of the map that we want to be hoverable. We are also going to set the text-indent so that the name of the region will not show up (there are plenty of other image replacement methods to achieve this; here is one good article on that). We are also going to add outline:none; to get rid of the pesky dotted outline that you get when you click on the link in some browsers. I am including a version that has a border applied to the <li>’s to see the area we are defining. See the map regions with outlines here.

.canada { top: 0;}
.america { top: 160px; }
.mexico { top: 320px; }

.canada a{ text-indent:-1000px; width: 542px; height:250px; outline:none;}
.america a { text-indent:-1000px; width: 542px; height:250px; outline:none;}
.mexico a{ text-indent:-1000px; width: 542px; height:270px; outline:none;}

 

Creating the Hover Effects

So now we have our map and our links sized and placed on top of the regions. Next we want to apply the :hover effect to each of our links. On hover we want to add the same background image, but if we stopped here, the maps wouldn’t line up when you hovered over the link. You remember the big master image, right? With that in mind, we want to set the vertical and horizontal background positioning so that our highlighted areas are aligned when we hover over the link. For the <li> with the class .canada, we want to set the the horizontal positioning to -554px so that the portion of our map with Canada highlighted displays in the exact position that the original one did. Because the top of the original background image and the top of our hoverable area are already aligned, we do not need to change the vertical background position, so we have set it to 0. From there, just apply the appropriate positioning to the other links so that their highlighted areas match up as well.

.canada a:hover {background: transparent url(US_Map.jpg) -554px 0px no-repeat;}
.america a:hover {background: transparent url(US_Map.jpg) -1108px -160px no-repeat;}
.mexico a:hover {background: transparent url(US_Map.jpg) -554px -320px no-repeat;}

If you will recall, in the master image, we have Canada and Mexico highlighted in the same map however, because we are only showing the image inside of a defined area, we can save ourselves from creating a whole new instance of the map for every highlighted region if we know that one region will not display inside the hoverable area of another.

On a side note, this entire article is nothing new. We have just walked through how to apply this method to a map. there is a much more eloquently written article on CSS Sprites here by Dave Shea of Bright Creative.

This is a republished article that I wrote on site that is no longer available