Memoirs from the old web: server-side image maps

Before there was a culture of implementing any and every novel function of a website using client-side JavaScript, there was a feature of HTML which seems almost unused today, and which would be unlikely to be implemented in web browsers if proposed today; namely, image maps.

An image map is a normal image on a website which has different clickable regions which take you to different pages. Image map functionality allowed polygons of an image to be defined as independent hyperlinks.

There was an era of the web, in the late 90s to early 2000s, where the use of image maps was common — arguably, too common, with many websites adopting subsequently derided “mystery meat” navigation practices, where website navigation involved an image map and it was unclear which parts of the image would take you to which page.

There were two kinds of image map technology; of those who used image maps, most probably only remember the newer client-side image maps. However, there was also an older image map technology which is now almost forgotten, in the form of server-side image maps.

Client-side image maps. The newer client-side image maps allowed arbitrary polygons to be defined over an image. This had the advantage that browsers could tab through the various polygons to be activated for accessibility purposes, and didn't require server-side processing. It was fairly common to see client-side image maps being used for navigation purposes, over a single image with a number of different page titles written on it. It was also fairly common for it to be used in conjunction with framesets, using the target attribute on an area element.

An example of defining a client-side image map follows. The clickable regions are defined in a map element, and then referenced using the usemap attribute on an image. Note that no a element is needed here.

<!-- References an image map -->
<img src="image.png" usemap="#map1" />

<map id="map1" name="Map 1">
  <!-- An example of a rectangular area over an image -->
  <area shape="rect" coords="10,10,100,100"
        href="/foo"
        alt="Go to the Foo page"/>

  <!-- An example of a circular area over an image -->
  <area shape="circle" coords="50,50,200"
        href="/bar"
        alt="Go to the Bar page"/>

  <!-- An example of an arbitrary polygon over an image -->
  <area shape="poly" coords="10,10,100,10,100,100,10,100"
        href="/baz"
        alt="Go to the Baz page"/>

  <!-- Fallback if no other area matches -->
  <area shape="default"
        href="/default"
        alt="Go to the Default page"/>
</map>

A live example can be found here.

The ordering matters — the default shape, if used, needs to appear last. Moreover, you can exclude a polygon as a clickable area of a previously defined polygon by adding a later <area/> tag with no href attribute. (Historically, it appears there was a nohref="" attribute you were supposed to use for such areas, but since omitting href is sufficient, this is now considered obsolete.)

It was common in the 90s and 2000s for proprietary image editing applications (Paint Shop Pro, etc.) to provide GUI-based image map code generators, that allowed clickable polygons to be defined visually.

Server-side image maps. By comparison, server side image maps were at their core much simpler in their operation:

<a href="/foo"><img src="image.png" ismap="" /></a>

The ismap attribute on the image, somewhat oddly, modifies the behaviour not of the image but of the hyperlink containing it. If you activate the hyperlink by clicking on the image within it, rather than linking you to /foo, you are linked to /foo?X,Y, where X and Y are pixel coordinates within the image.

Of course, this ad-hoc query string construction is a little odd. This form of query string which is appended is fixed and cannot be changed. Moreover, if an URL already has a query string, for example /foo?bar, the resulting query string is /foo?bar?X,Y. If a hyperlink contains things other than the image, for example some additional text, and you click on the text, the URL in the hyperlink is not modified.

A live example can be found here.

In any case, the premise of server-side image maps was that the server would look up the coordinates and decide where to redirect you (an example of a mildly dynamic website).

Server-side image maps had quite a few disadvantages. Since the list of polygons wasn't known to the client, accessibility was basically nonexistent, nor could the targets of the different regions of such image maps be crawled by spiders.

However, there is one infrequently noted advantage of server-side image maps. While the list of polygons not being known to the client can generally be considered a bad thing as it undermines accessibility and crawlability, in some circumstances it can be desirable; namely, for puzzles. I recall a puzzle page (operated by Cyan, the creators of Myst, as I recall) which required you to find and click on a certain spot hidden within an image. The page used server-side image maps to prevent trivial cheating by examining the page's source code.

The only other advantage of server-side image maps was their wider support than client-side image maps, with support existing as long ago as Mosaic 1.1. Client-side image maps received support in Netscape Navigator 2 and Internet Explorer 2. Though my memories of the web don't date back as early as the times that those versions were current, I recall concern about browser support still being (perhaps residually) prevalent in online documentation and guidance for web development in the early 2000s. I suspect, based on a vague recollection, that there may have been (perhaps less common) browsers which supported rectangular and circular areas in client-side image maps, but not arbitrary polygons, but it is hard to find anything to confirm this.

For those curious, the behaviour of the ismap attribute is still documented to this day in the HTML5 specification, as a special case in the activation behaviour of an a element. Client-side image maps are defined here. And for the curious, no — client-side and server-side image map functionality can't be combined.

Form-based server-side image maps. It turns out there is final third obscure image map function in the web platform, one which even I wasn't aware of until someone mentioned it: <input type="image"/>. On the face of it this is simply a way to make a form button which is an image, and might seem to be obsoleted by the modern <button> element which can contain an <img/>. However, it turns out that <input type="image"/> automatically adds x and y fields to the submitted form, based on the coordinates clicked in the image. See the MDN docs. Thus there are actually two kinds of server-side image map; one using <img ismap=""/> and one based around <input type="image"/>.