Oct
2nd

How To: Build An Image Map with CSS

You may have noticed that I recently added a nice graphic to my sidebar for my RSS feed, email subscriptions, and mobile feed. I wanted something ‘geeky’ so I decided on a ‘pocket’ graphic that holds all the subscription methods for my blog.

In the days of Web 1.0, a collection of links like this could be built by splicing up your image up with links on each graphic, then trying to sew it all back together with a table. It could also be accomplished by utilizing an image map but that usually requires a tool to build out the coordinate system. Utilizing Cascading Style Sheets makes this a ton easier… no splicing images and no trying to find a tool to build your coordinate system!

  1. Build your image that you’d like to use. You can utilize this graphic below… I’ve got the working version up on the sidebar, this is simply displaying the graphic (right-click and save as to download):
    Options
  2. Upload your image to a directory that’s relative to your CSS. In WordPress, this can be done easiest by placing it in an images folder in your theme directory.
  3. Add your HTML. It’s nice and simple… a div with three links in it:

    <div id="subscribe">
    <a id="rss" href="[your feed link]" title="Subscribe with RSS"><span class="hide">RSS</span></a>
    <a id="email" href="[your email subscribe link]" title="Subscribe with Email"><span class="hide">Email</span></a>
    <a id="mobile" href="[your mobile link]" title="View Mobile Version"><span class="hide">Mobile</span></a>
    &lt;/div&gt;

  4. Edit your Cascading Style Sheet. You will be adding 6 different styles. 1 style for the overall div, 1 for the a tag so it doesn’t display any text decoration, 1 style to hide the text (used for accessibility) and 1 style specification for each of the links:

    #subscribe { /* background image block */
    display: block;
    width: 215px;
    height: 60px;
    background: url(images/options.png) no-repeat;
    margin-top: 0px;
    }
    #subscribe a {
    text-decoration:none;
    }
    .hide {
    visibility:hidden;
    }
    #rss { /* RSS Link */
    float: left;
    position:absolute;
    width : 50px;
    height: 50px;
    margin-left: 20px;
    margin-top: 5px;
    }
    #email { /* Email Link */
    float: left;
    position:absolute;
    width : 50px;
    height: 50px;
    margin-left: 70px;
    margin-top: 5px;
    }
    #mobile { /* Mobile Link */
    float: left;
    position:absolute;
    width : 50px;
    height: 50px;
    margin-left: 130px;
    margin-top: 5px;
    }

The positioning is nice and simple… add a height and width and then set the left margin from the left side of the image, and the top margin from the top side of the image!

This “How To” post is for entry into the Geeks are Sexy ultimate “How To” Contest! One note, it is true that an image map can have much more complex polygons, but I haven’t really seen too many places where that’s a must have. I did notice that big ol’ RSS image on the Geeks are Sexy sidebar… that’s a good place for a link. ;)

UPDATED 10/3/2007 for better accessibility with the advice of Phil!

  • My online image mapping tool now does CSS image maps as well as HTML image maps.

    here is the link
    online image map tool - html & css
  • Hi Doug - I'm building out a rather complex css-based image map that also has remote rollovers (in this case, text displays elsewhere on the page when you hover one of the image hotspots). Any way, I came across your example here while researching that... and I thought I'd share the following input:

    1. For accessibility, you shouldn't use visibility:none (or display:none if you considered that) to hide the text here, as an element styled with visibility: hidden will not be read by screen readers (those that follow spec).

    Instead, use a more robust image replacement technique. I suggest either the Phark method or Gilder/Levin - those are just the better documented names to google to find the basic techniques. I prefer G/L as it also works with CSS enabled but images are turned off.

    2. While I don't see it breaking (using FF3), your implementation of positioning also has inherent risks. An absolutely positioned element is positioned relative to its closest positioned parent. Basically, you'd want to explicitly set a positioning context by applying 'position:relative' to #subscription. Then the children (the positioned links) can be positioned within that parent. This method helps ensure more reliable results across browsers.

    Also, you should then use the positioning declarations of "top: x" and "left: x" (where x is the offset value, say in px) rather than margins to handle that positioning. Again, I don't necessarily see it breaking the way you have it, but top and left are meant for this so why not use them? Plus you've got floats and margins set on the same element, which under specific conditions cause the "double margin" bug in IE6 (did you test this there?) - while there is a fix, you avoid that issue entirely by using top and left instead of margins for positioning in this case.

    3. Finally, why not use a semantically sound unordered list for these links instead of the meaningless div?

    Sorry for droning on... I just like to share, b/c I know from experience how there are many different ways to use CSS to get a desired result, but some ways certainly do work better (more reliable, cross-browser) than others. HTH.
  • hello, i built my website on joomla...i want to use this method to make the logo of my page a link to home, i have been told u can not do this with joomla but this article gives me hope! help via email would be muchly appreciated....thank you
  • tess malloy
    i'm currently using a template layout and editing with my own stuff. I want to add an image map, but i'm not sure where to place it in the css. the image i want to make a map of is in the header part.
  • Would a similar approach be used for a larger and more complicated image map like I am trying to use?

    If you view my site, click on links to the left and you'll see the image I'm trying to use as an image map (under the Text alphabet).

    Basically, trying to use the Image to go to each section of this list by letter.

    Evidentally, I spent 20 minutes building a map with GIMP, and then WP removes the map tags, so that's how I found your site.

    Though, may contemplate using Flash

    Thanks.
blog comments powered by Disqus