CSS Image Map

From Exterior Memory
Jump to: navigation, search

I wanted to have an image map with mouse-over effect: that is, one image with clickable "hot spots". You can find the result at http://www.macfreek.nl/

I have to credit everyone who already looked in this idea using CSS. Since it was for my homepage, I wanted a solution that used standards only, and was viewable by a wide range of browsers.

HTML

I finally ended with a solution with as HTML:

<div id="imagemap">
  <h1>Title</h1>
  <ul>
    <li id="link1"><a href="#"><span>First Link</span></a></li>
    <li id="link2"><a href="#"><span>Second Link</span></a></li>
  </ul>
</div>

Where the #imagemap div would be replaced by a image, and the #link1 and #link2 id are used to position the links on the image. The reason I used the div was because I wanted the Title to appear on top of the imagemap as well. Otherwise, I could have used <ul id="imagemap">. The mouse-over effect was achieved using an overlay image using a:hover.

#imagemap { 
  position: relative; width: 400px; height: 300px; 
  background: url(imagemap.png) top center no-repeat;
}
#link1 {
  position: absolute; left: 454px; top: 599px;
}

Note that two techniques are important here:

  • CSS Positioning. You really must understand positioning in CSS, otherwise you might make the mistakes like using a float.
  • CSS Image Replacement. The replacement of a link with an (overlay) image is the second technique you must master.

If you combine this with the use of :hover pseudo-selector, you can create image maps.

Use one Image to avoid flickering

If you use multiple images (one for the background, and another one for each link), you will notice a flickering when the mouse hovers over an image. This flicker is caused by the time it takes for your browser to load the image. You can avoid this delay by making sure the image is already loaded.

Now, you can do this using a Javascript to prefetch the images (download at onLoad()). However, another technique is to simply use the same image. Obviously, all images are then ready to use.

This image combines both the background image and the overlay images for the links in a single file.

For the background image, you make sure that the width and height are correct, so that only the part of the image you want to be shown is actually shown:

#imagemap { background: url(homepage-combined.jpg) top center no-repeat;
            width: 770px; height: 768px; }

For the overlay images, you use another region of the same image:

#link1 a { width: 247px; height: 220px; }
#link1 a:hover { background: url(homepage-combined.jpg) -106px -775px no-repeat; }

See the sample picture shows how such a combines image will look like.

Real life examples

I based my findings on seven examples I found on the web. I tested each example in a wide range of browsers, and used the techniques that worked in most browsers. The result is located at http://www.macfreek.nl/

I looked at these criteria:

  • Does the HTML markup use a list (dl, ul, or ol) as the basics?
  • Does the HTML markup make sense (e.g. in Lynx)
  • Does it not rely on Javascript for prefetching images (but uses a filter image -e.g. a transparent png image, or a single image)
  • does it suffer from the many Internet Explorer bugs (e.g. flawed box scheme)
  • does it allow to display text beneath the clickable link
  • will the hover only work if the mouse is over the actual link, or is there an additional clue (e.g. visible border) where links are when the mouse is hovering over other parts of the image.

Here are the examples I looked at:

  1. http://www.frankmanno.com/ideas/css-imagemap-redux/ (li; filter over image with text)
  2. http://www.frankmanno.com/ideas/css-imagemap/ (li; single image with text)
  3. http://www.alistapart.com/d/imagemap/example2.html (image tabs; relies on Javascript for image prefetching)
  4. http://www.alistapart.com/d/sprites/ala-blobs2.html (single image; empty li)
  5. http://www.cssplay.co.uk/menu/old_master.html (box with detail pop-up; click clue when hovering over image; very pretty)
  6. http://evan.nixsys.bz/note/ (option 4; filtered box with text; click clue when hovering over image)
  7. http://www.webreference.com/programming/image_map/examples/ten.htm (box with detail pop-up; click clue when hovering over image)
  8. http://www.macfreek.nl/ (result: click clue when hovering over image, single image with text, non-empty dt)

And here are how the above results look like in these browsers (except the first all Mac OS applications):

1 2 3 4 5 6 7 8
IE 5.0.0 Windows (Win98) - ~ ~ + + - ~ + (also border is OK)
Internet Explorer 5.2.3 ~ ~ + + + - ~ + (B: minor flaws in text rendering; border error)
Camino 0.7.0 + + + + + - + +
iCab 2.9.8 - - - - - - - - (clickable at wrong location)
iCab 3.0b + + ~ + ~ + + +
Netscape Communicator 4.8 c ~ ~ - - - - - ~ (image partly visible; regular links)
Netscape 7.0 + + * + + - + +
Mozilla 1.2.1 + + + + + + + +
Mozilla 1.5.1 + + + + + + + +
Mozilla Firebird 1.4 + + + + + + + +
Firefox 1.0.4 + + * + + + + +
Firefox 1.5 + + + + + + + +
Opera 5.0b4.498 - ~ ~ - ~ - ~ ~ (clickable at wrong location)
Opera 7.54 ~ + + + + + + +
Opera 8.0b ~ + * + + + + +
OmniWeb 4.1.1  ?  ?  ?  ?  ?  ?  ?  ? app crashes
OmniWeb 5.1.2 + + ~ + * + - +
Safari 1.0  ?  ?  ?  ?  ?  ?  ?  ? doesn't work on recent OS
Safari 1.2 ~ + * + * + - +
Safari 2.0.2 ~ + + + * + - +
Lynx 2.8.5 ~ ~ ~ - ~ ~ ~ + (regular li list)
EyeHome browser  ?  ?  ?  ?  ?  ?  ?  ?
^ ^

Legend:

+ = perfect
* = near perfect (slow image load)
~ = reasonable, not perfect (e.g. no css, still readable)
- = incomprehendable

I decided to base my "ideal" imagemap on links 2 and 4:

  1. http://www.frankmanno.com/ideas/css-imagemap/ (li; single image with text)
  2. http://www.alistapart.com/d/sprites/ala-blobs2.html (single image; empty li)