Kimler Sidebar Menu
Kimler Adventure Pages: Journal Entries
Invalid ImageMaps in XHTML v1.1
Posting a valid XHTML 1.1 ImageMap -> Hey, What's Going On?
I recently began validating against the XHTML 1.1 standard, rather than the XHTML 1.0 (Strict) standard. There isn't much of a change between the two, so the move wasn't too difficult. However, while checking validation on some old entries, I noticed that image maps yield errors.
I tried fixing the validation problems, but the result was an image map like the one on this page. It validates fine against the 1.1 standard, but doesn't work - either in IE or FireFox. (You can check this with the validation button ... but do it before opening the "Read Full Story" link).
At first, I thought I was coding the thing wrong. Then, I thought that maybe the W3C Validator had a bug. This is the kind of problem that will make you run around and chase your tail!
I couldn't let it lie. (After posting instructions for coding image maps that validate against the XHTML 1.0(strict) standard, I was determined to figure out what was going on.)
XHTML 1.0 (Strict) ImageMap: Invalid in 1.1, but Works
The image map on the right is the same one that I posted in the original post. It validates to the XHTML 1.0 (Strict) standard and continues to work in XHTML 1.1, but it doesn't validate. A validation check returns the following three error messages, which you can verify.
(1) There is no attribute "name".
(2) Character "#" is not allowed in the value of attribute "usemap".
(3) Non-existent ID "#mapName2".
The Old XHTML 1.0 Strict Code That Works
< map name = "MapName2" id = "MapName2" > < area shape = "rect" coords = "14,123,197,223" href = "http://nike.com" alt = "hotspot"& gt; </area> </map> <img src = "http://www.yoursite.com/imagemap.jpg" style = "width:400px; float:left; border:1px solid #369;" usemap = "#mapName2" alt = "image" />
The higlighted code shows the problem areas. (Note: Though IE works with just id="mapName2", Mozilla-based browsers require name="mapName2". Both are allowed in XHTML 1.0 (Strict) and both are needed for the image map to render properly in both browsers.)
Looking Under the Hood of the DTD
<!ELEMENT img EMPTY>
src %URI; #REQUIRED
alt %Text; #REQUIRED
longdesc %URI; #IMPLIED
height %Length; #IMPLIED
width %Length; #IMPLIED
usemap %URI; #IMPLIED
ismap (ismap) #IMPLIED
<!ELEMENT map ((%block; | form | %misc;)+ | area+)>
id ID #REQUIRED
class CDATA #IMPLIED
style %StyleSheet; #IMPLIED
title %Text; #IMPLIED
name NMTOKEN #IMPLIED
In the "img" element, you'll notice that the "usemap" attribute is defined as being a %URI. This means that # (pound sign) can be used, as it specifies a link to a 'fragment identifier' in the current page. (Source: Dan's Web Tips)
For the "map" element, the "id" attribute is required (it MUST be present). This explains why using name="mapName2" alone, will not validate for the FireFox browser in XHTML 1.0 (Strict). Lastly, we see that the "name" attribute is "#IMPLIED" (or optional).
Compare to the XHTML 1.1 DTD, which has been modularized (instead of a single DTD file, there are 4 'core' DTD modules and a number of 'abstract', or optional, modules). The XHTML 1.1 HyperText Core Module is one of the four and the one that contains the attribute definitions for images and client-side image maps. The format of the file is somewhat different, but a similar comparison can be made.
<!-- modify form input attribute definition list
to allow for client-side image maps
usemap IDREF #IMPLIED
><!ENTITY % map.attlist "INCLUDE" >
id ID #REQUIRED
Notice how the "usemap" attribute for the "map" element is now an IDREF in the XHTML 1.1 DTD, rather than a URI? This means that this value "must be the same value as the ID attribute of the other element". (Source: James Q. Jacobs) This is why the # yields an error AND why it can't reference the ID as well (since the ID doesn't contain a pound sign).
Also, the "map" element no longer carries the "name" attribute, which we already knew. Just the "id" is used and, as before, it is manditory.
Now that we know the rules, we know WHY the code on the front page (seen below) validates under XHTML 1.1. This made me feel a little better, as it proved that it wasn't a coding error. But why doesn't the bloody thing WORK?
The NEW XHTML 1.1 Code That Doesn't Work
< map id = "MapName2" > < area shape = "rect" coords = "14,123,197,223" href = "http://nike.com" alt = "hotspot"& gt; </area> </map> <img src = "http://www.yoursite.com/imagemap.jpg" style = "width:400px; float:left; border:1px solid #369;" usemap = "mapName2" alt = "image" />
The Bottom Line: It ain't valid, but it works.
It's not a bug in the W3C validator and it isn't that the code is improperly formed.
Browsers just haven't caught up to the 2001 W3C XHTML 1.1 recommendation. (Maybe it just fell through the cracks?) They still DO, however, understand the OLD way, which is why the old code still works. Oddly, IE accepts the newer "id"-only approach, while Mozilla (FireFox) must have the older "name" attribute. (And they call Mozilla a "modern browser" ... bah!)
There's not much of a choice here. If you want an image map that FUNCTIONS, you must write invalid XHTML 1.1 code. This is the ONLY situation that I've come across (so far), where I haven't been able to write valid XHTML code and accomplish what I want. So ... break the standard and feel good about it!
One of these days, after a new browser version release, someone will comment that the first image map is working. Then I'll have a little party, do a little dance, and delete this entry.