For most of the history of the web, linking to a point within a document
meant linking to an a element with a name attribute at
that point in the document. To create the linking URL, you added a pound sign (#) and the
name value to the page’s URL to link to that point in the page. If there was no a element with a name attribute at that point, you couldn’t link to that point.
For example, if you go to
href="http://www.w3.org/TR/REC-xml-names/#ns-decl" rel="tt:Abstraction/Example">http://www.w3.org/TR/REC-xml-names/#ns-decl, do a View
Source, and search for “name=’ns-decl’,” you’ll see the <a
NAME=’ns-decl’> tag that let you use that URL to jump directly to the “Declaring
Namespaces” section of the “Namespaces in XML” Recommendation.
This was possible because the a (”anchor”) element, in addition to
its most popular role as the starting point of a link, could be a link
endpoint if it had a name—or, in geekier parlance, if it had
SGML always let you give any element identity; you just
declared an attribute for it with an attribute type of ID instead of NMTOKEN,
CDATA, or one of the other attribute type choices. (To make things more
confusing, while virtually no one ever named an attribute “nmtoken” or
“cdata,” the most popular name for attributes of type ID was always “id.”) If
an attribute of type ID in an SGML document had a particular value, no other
attribute in that document that had also been declared to be of type ID,
regardless of the attribute’s name (”id,” “uid,” “empnum,” or whatever), was
allowed to have the same value. Part of a parser’s job was to report any ID
attribute value duplication as an error.
When SGML was being simplified into XML, some suggested that,
if DTDs were being made optional, parsers should assume that any attribute
named “id” was of type ID. This suggestion didn’t make the cut for the 1.0 Recommendation,
although the suggestion still crops up in any discussion of potential XML modifications (in fact, it did just this month; see update below). XML 1.0 handles ID attributes the same way SGML did: you have to declare id attributes as having type ID, they don’t have to be named “id,” and most people name them “id” anyway.
While the HTML a element had a name attribute
since its first
DTD, it didn’t get an optional id attribute until around HTML
doesn’t have it and href="http://www.w3.org/TR/1999/REC-html401-19991224/struct/links.html#h-12.2"
shape="rect" rel="tt:C-source">4.01 has it along with the other href="http://www.w3.org/TR/1999/REC-html401-19991224/sgml/dtd.html#coreattrs"
shape="rect" rel="tt:C-source">core attributes.) XHTML had it from the beginning, and the href="http://www.w3.org/TR/xhtml-modularization/">Modularization
of XHTML Recommendation actually href="http://www.w3.org/TR/2001/REC-xhtml-modularization-20010410/abstract_modules.html#s_nameidentmodule" rel="tt:C-source">deprecates the use of the module that declares the
a element’s name attribute. For backward
compatibility, it makes the name attribute available, and tells us
that “if the name attribute is defined for an element, the
id attribute must also be defined. Further, these attributes must
both have the same value.” (A View Source on this document shows that it
practices what it preaches: this “Name Identification Module” section includes
the tag <a name=”s_nameidentmodule” id=”s_nameidentmodule”> in
Of course, what the specs say is purely academic if the
browsers don’t implement it. I only recently found out that you can point
recent releases of Mozilla, Internet Explorer, and Opera directly at any
element (and that’s any element, not just the a element) in
an HTML document that has an id attribute by adding a pound sign and
the id attribute’s value to the URL for that document. For example,
the paragraph above beginning “SGML always let you” has an id
value of “p2″ with no a element near it, and the
link in this sentence jumps to “#p2″. Try it.
This means a lot for web linking: it means the bar has been
lowered for linking into fairly arbitrary points within documents. It just
wasn’t practical to ask people to add lots and lots of a elements
with name attributes to all of their documents. Some
people like to think that XPointer will make this kind of arbitrary addressing easier,
but even if all browsers supported XPointer (Mozilla 1.4, currently in beta,
support) the use of XPointer assumes that the target document is
well-formed, which is too much to assume for most of the web. It’s much more reasonable to hope for increasing use of id attribute values in HTML documents.
And, apparently, it’s already in progress! When I began
writing the preceding paragraph, I didn’t remember where I had heard about
Mozilla’s burgeoning XPointer support, so I did a Google search and found the
appropriate page. When I found the part of the page that I needed, I did a
View Source and saw it enclosed in a div element with an id
value of “linking,” so I was able to use that as my link target. I didn’t have
to wish “if only there was an a element with a name
attribute there…” as countless web page authors have wished about countless
potential web linking destinations since the web began. This is progress, and
I’m psyched. I’m going to get in the habit of adding id attributes to
my block-level HTML elements; all it takes is a short XSLT stylesheet. The
more we all do it, the more we can do with the web.
Update, May 19th: When I wrote this, I didn’t know about Chris Lilley’s summary of XML ID issues for the W3C’s Technical Architecture Group, How should the problem of identifying ID semantics in XML languages be addressed in the absence of a DTD? It’s required reading for anyone interested in ID issues in XML.
Do you see more use of id attributes in HTML? Am I missing anything here?