Image Maps used to be all the rage on Web sites, back when designers were dictating the look of sites...before the usability & accessibility folks took over. Image maps have lost favor as Web developers have moved towards simpler and less presentational markup, despite the fact that traditional image maps are a perfectly valid part of XHTML. In this exercise we will look at a nice compromise, way to create image maps with CSS.
Obviously, we need an image to work with; you can download this one to experiment with. Place the image in a root folder, then create a new HTML document. Save it as imageMap.html
Place the image on the page and wrap it in a <div>:
<div id="pic">
<img src = "images/3girls.jpg" alt="Three girls" width="800" height="532">
</div>
Now an image map contains hot spots that link to other pages or sites. So we need to create a set of links. We will do this by creating a simple list and placing it within our <div>:
<div id="pic">
<img src = "images/3girls.jpg" alt="Three girls" width="800" height="532">
<ul>
<li id="ellie">
<a href = "http://www.danfergusdesign.com" title="Ellie" target="blank">Ellie</a>
</li>
<li id="rachel">
<a href = "http://www.boatnerd.com" title="Rachel" target="blank">Rachel</a>
</li>
<li id="julie">
<a href = "http://www.google.com" title="Julie" target="blank">Julie</a>
</li>
</ul>
</div>
Note the inclusion of title attributes; this will cause the name of the person to pop-up when her hotspot is rolled-over in most browsers. This is optional; you can get rid of it if it doesn't suit your purposes.
Now for the CSS. We need to set the size of the <div> so that it matches the image, and we need to set it's position to relative, so we can absolutely position the list items (hotspots) later:
#pic {
width: 800px;
height: 532px;
position: relative;
}
Now let's hide the list's bullets and kill the margins & padding:
#pic ul {
margin: 0;
padding:0;
list-style: none;
}
Next we'll style the links. To create hotspots, we need to give each link a size. The size is arbitrary; choose a size that works best for your particular image. We also will position each link absolutely. We could write position:absolute three separate times for each link, but why not save time and writing by doing for all three at once? We'll then set the individual coordinates for each one later. Oh, and we'll hide the text by shoving it off to the left:
#pic a {
position: absolute;
width: 120px;
Height: 140px;
text-indent: -999em;
}
We can now set the positions for each hotspot. Obviously, these coordinates correspond to this particular image; you'll have to find your own coordinates for your images of your own.
#pic #ellie a {
top: 145px;
left: 116px;
}
#pic #rachel a {
top: 159px;
left: 332px;
}
#pic #julie a {
top: 172px;
left: 590px;
}
At this point they should work; try it out. Here's one more thing you can add: a border that appears around the hotspots when they're rolled-over:
#pic a:hover {
border: 2px solid #fff;
}
The method above uses pop-up "tool tip" boxes with titles. We can use CSS to create more sophisticated pop-up captions that we can style and place where we want.
Re-save the previous page we created as imageMaps2.html so we don't overwrite it. We need to make one small addition to the markup—a set of <span> tags around each link. Also, delete the titles (the sections that are struck-through below):
<div id="pic">
<img src = "images/3girls.jpg" alt="Three girls" width="800" height="532">
<ul>
<li id="ellie">
<a href = "http://www.danfergusdesign.com" title="Ellie" target="blank">
<span class="note">Ellie</span>
</a>
</li>
<li id="rachel">
<a href = "http://www.boatnerd.com" title="Rachel" target="blank">
<span class="note">Rachel</span>
</a>
</li>
<li id="julie">
<a href = "http://www.google.com" title="Julie" target="blank">
<span class="note">Julie</span>
</a>
</li>
</ul>
</div>
The CSS is very similar to the first example. However, we need to make some changes to the #pic a style:
#pic a {
position: absolute;
width: 120px;
Height: 140px;
text-indent: -999em;
text-decoration:none;
color:#000;
font-family:Arial, Helvetica, sans-serif;
}
First, I removed the text-indent. I then removed the underline and chose a text color and font (you can pick your own of course). Now we need to write a style rule for the span, which we called "note":
#pic a .note {
position:absolute;
bottom:-3em;
width:5em;
padding:.2em .5em;
background-color:#ff6;
text-align:center;
left: -999em;
margin-left:-3em;
}
That's a lot of ems! Let's go through them one at a time. First, the notes are positioned absolutely; their containing block is the hotspot, so they will be positioned relative to our hotspot boxes. The style property bottom:-3em positions the span boxes 3ems below the hotspots, but flush left. We set a width for the caption boxes (I've chosen 5ems, but you could go larger if you have longer captions). The padding creates space around the text within the caption box. Background-color and text-align are self-explanitory (feel free to choose your own color). The next two lines is where things get a little tricky; left: -999em hides the captions off-screen until we call them with a rollover (below). Margin-left: -3em aligns the middle of the caption boxes (when they reappear) with the left edge of the hotspots. The caption boxes are 6ems wide (5ems + .5em padding on each side). Why align the boxes this way? Well, when we make them reappear in the next step, we will position them 60px from the left edge of the hotspot box, which is half the size of the hotspots. This will effectively center the captions under the hotspots:
#pic a:hover .note {
left: 60px;
}
Try it. Note that if you change the size of either your hotspots or your caption boxes, you will have to recalculate your positioning amounts.
A remote rollover is a hover event that triggers a change somewhere else on a page. They're pretty common in Flash, and can be made fairly easily with javascript. We can accomplish the same affect with CSS but nesting several elements inside the same link. These elements are then positioned separately. But since they belong to the same parent link, a single roll-over will trigger each (or all) of them. This allows us to hover over one element and change the appearance of another. Of course, we more or less did this already with the last example. Let's take it a step further.
Once again re-save your html page as imageMap3.html.
We need to make a few more adjustments to the markup. We need to add an empty span on which to hang our hotspot styles, and we've changed the class names around the names from "note" to "link":
<div id="pic"><img src="images/3Girls.jpg" alt="3 girls" width="800" height="532" />
<ul>
<li id="ellie">
<a href = "http://www.danfergusdesign.com" target="blank">
<span class="hotspot"></span>
<span class="link">» Ellie</span>
</a>
</li>
<li id="rachel">
<a href = "http://www.boatnerd.com" target="blank">
<span class="hotspot"></span>
<span class="link">» Rachel</span>
</a>
</li>
<li id="julie">
<a href = "http://www.google.com" target="blank">
<span class="hotspot"></span>
<span class="link">» Julie</span>
</a>
</li>
</ul>
</div>
Note the inclusion of a special character before each name; this is strictly optional.
The styles for #pic and #pic ul remain the same:
#pic {
width: 800px;
height: 532px;
position: relative;
}
#pic ul {
margin: 0;
padding:0;
list-style: none;
}
Now we'll write some rules for the hotspots:
#pic a .hotspot {
position: absolute;
width: 120px;
height: 140px;
}
#pic #ellie a .hotspot {
top: 145px;
left: 116px;
}
#pic #rachel a .hotspot {
top: 159px;
left: 332px;
}
#pic #julie a .hotspot {
top: 172px;
left: 590px;
}
These rules create the hotspot boxes and position them absolutely, just as we had done previously. However, this time we hung the styles on the empty span called hotspot, rather than the anchor tag itself.
Now we need a similar set of styles for the text links. We want these to appear below the image:
#pic a .link {
position:absolute;
width:6em;
font-family:Arial, Helvetica, sans-serif;
padding: .2em .5em;
}
#pic #ellie a .link {
bottom: -2em;
left:0;
}
#pic #rachel a .link {
bottom: -3.5em;
left:0;
}
#pic #julie a .link {
bottom: -5em;
left:0;
}
Like the hotspots, these are positioned absolutely. I've also added some padding to the text boxes and specified a font; as always, you can modify these to suit your purposes.
Now to create the rollover effects we add two reciprocal style rules:
#pic a:hover .hotspot {
border: 2px solid #fff;
}
#pic a:hover .link {
color:#f00;
background-color:#ff9;
}
The first rule causes a border to appear around the hotspot; the second cause the link text to change color and gain a background color. Both are triggered by the same action.
That should be it; what we have will work in most browsers. However, IE has a bug (surprise!) that prevents this from working properly. So we need to add one more rule to make this work in IE:
#pic a:hover {
border:none;
}
Now we should be good to go.