CSS3 Image Maps

Skip to Example

Image MapsIt's been more than seven years since I first published my CSS Image Maps article/tutorial. I've received numerous emails from people thanking me for showing how it's done that I thought I'd update it to make it more relevant to the CSS capabilities of today's modern browsers.

Today's solution requires less code, needs no images (apart from the one you're using for the map, no doubt) and offers some nice sprinkles of CSS3 transitions, including fading and animating the "info bubble" when hovering over an annotated area on the image.

I took the existing CSS, cleaned it up to make it a little more modular (and less DRY) and, as always, have provided a working example. Below is the required code to create your own CSS3 Image Map:



            <dl id="inTheStudioMap">
                <dt class="title">In The Studio...</dt>
                <dt id="screen">1. Screen</dt>
                <dd id="screenDef"><a href="#"><span>Ableton, FTW!</span></a></dd>
                <dt id="synth">2. Virus TI</dt>
                <dd id="synthDef"><a href="#"><span>Sweet sounds from the Virus</span></a></dd>
                <dt id="snacks">3. Snacks</dt>
                <dd id="snacksDef"><a href="#"><span>Mmmmm, snacks.</span></a></dd>


            /* image map container (and actual image) */
                margin: 0;
                padding: 0;
                background: transparent url(studio.jpg) top left no-repeat;
                height: 299px;
                width: 400px;
                position: relative;
                box-shadow: 0 0 5px rgba( 0, 0, 0, 0.5 );
                border: 5px solid #fff;

            dd a{
                position: absolute;
                outline: none;
                text-decoration: none;
                border: 1px solid #FFFCE6;
                background: rgba( 255, 255, 191, 0.4 );
                text-shadow: 0 1px 0 rgba( 255, 255, 255, 0.9 );

                -webkit-transition: background 1s ease-in-out, border 1s ease-in-out;
                -moz-transition: background 1s ease-in-out, border 1s ease-in-out;
                -o-transition: background 1s ease-in-out, border 1s ease-in-out;
                -ms-transition: background 1s ease-in-out, border 1s ease-in-out;
                transition: background 1s ease-in-out, border 1s ease-in-out;

            dd a:hover{
                background: rgba( 255, 255, 255, 0 );
                border: 1px solid transparent;

            dd a:active{
                outline: none;
                -moz-outline: none;

            dd a span{
                opacity: 0;
                visibility: hidden;
                position: absolute;
                left: -1px;
                top: 0;
                height: 20px;
                line-height: 20px;
                text-indent: 0;
                vertical-align: top;
                background-color: #F4F4F4;
                font-weight: bold;
                color: #333;
                border: 1px solid #F4F4F4;
                margin: 0;
                padding: 5px;
                white-space: nowrap;
                box-shadow: 0 0px 5px rgba( 0, 0, 0, 0.5 );

                -webkit-transition: all 1s ease-in-out;
                -moz-transition: all 1s ease-in-out;
                -o-transition: all 1s ease-in-out;
                -ms-transition: all 1s ease-in-out;
                transition: all 1s ease-in-out;

            dd a span:after{
                border: 10px solid #F4F4F4;
                width: 0;
                height: 0;
                content: '';
                position: absolute;
                border-color: #F4F4F4 transparent transparent;
                left: 5px;
                bottom: -21px;
                opacity: 1;

            dd a:hover span, dd a:focus span{
                visibility: visible;
                opacity: 1;   
                top: -45px;

             * Hotspot Positions
             * - replace with location to your annotations
            dd#screenDef {
                top: 77px;
                left: 120px;

            dd#screenDef a {
                width: 115px;
                height: 80px;

            dd#synthDef {
                top: 180px;
                left: 225px;
            dd#synthDef a {
                width: 80px;
                height: 36px;

            dd#snacksDef {
                top: 220px;
                right: 159px;
            dd#snacksDef a {
                width: 85px;
                height: 40px;

A working example can be viewed below (the image was taken while working on our latest remix [due out soon]):

In the studio...
In The Studio...
1. Screen
Ableton, FTW!
2. Virus TI
Sweet sounds from the Virus
3. Snacks
Mmmmm, snacks.

If you have any questions, concerns, and/or suggestions for improvement, please feel free to send me a note: frankmanno [-at-] gmail [-dot-] com or contact me via twitter (@frankieshakes).

The examples have been succesfully tested in Chrome, Safari and Firefox (Mac). If you're able to test this out on other browsers, please send me a note, and I'll update the listing.


This article has been translated into the following languages:

If you'd like to translate it into another language, feel free to contact me with a link to the translated version.