All That We Can Leave Behind
April 16, 2003
Last month I promised an article on the venerable <img>
tag, which has
been dropped from XHTML 2.0. It was supposed to be a gentle introduction to "stuff
we lose
in XHTML 2.0, and what we gain in return". However, during the course of researching,
I
realized that it was turning out to be not so introductory after all. So you'll have
to wait
another month for that.
There are several key elements and attributes that are slated to be dropped from XHTML 2.
<br />
has been dropped, replaced by<l>...</l>
.- The inline
style
attribute has been dropped, but there are still plenty of ways to define styles. <img />
has been dropped, replaced by<object>...</object>
. As we'll see in next month's article, this may present some serious migration difficulties.- HTML forms have been dropped, replaced by XForms. This is such a major change that it also deserves its own article.
The q
element has also been dropped, replaced by <quote>
;
but nobody uses <q>
because Internet Explorer for Windows doesn't support
it: it's hardly even worth mentioning, except for completeness.
Lines or Breaks?
<br/>
is dead; long live <br/>
. Certainly one of the
most abused elements in HTML, and later XHTML, <br/>
's fame dates back to
the Netscape 4 era, when CSS was sketchy at best and "using the proper element" meant
you
were a chump whose pages looked like amateur scribblings. To migrate from
<br/>
, the first thing to do is see if there's a more suitable
element.
For example, if you wanted a list of links along the side of your page, every Netscape
4-era coder knew that you couldn't use proper list markup and CSS, because Netscape
4 would
force those unsightly list bullets on you, and no amount of CSS could override them.
Even in
later versions when this was fixed, it would still stubbornly leave an indented left
margin.
So nobody used proper list markup: everyone either used tables for layout with each
link in
a separate table cell or they used <br/>
, like this:
<a href="/">Home</a><br /> <a href="/about/">About</a><br /> <a href="/news/">News</a><br />
Although this is technically valid markup (it will pass the W3C's XHTML validator), your life will be easier in the long run if you switch to using real list markup. With the right mix of CSS, you can make it look exactly like it used to and no one will notice the difference. (Okay, that's not entirely true. As you might expect, this fails in Netscape 4.) This is what it might look like using real list markup:
<style type="text/css"> ul.nl { list-style: none; margin-left: 0; padding-left: 0; } </style> ... <ul class="nl"> <li><a href="/">Home</a></li> <li><a href="/about/">About</a></li> <li><a href="/news/">News</a></li> </ul>
This works today in XHTML 1 and will continue to work in XHTML 2. However, XHTML 2
defines
a new element, nl
, specifically for navigation lists. If you upgrade now to use
real list markup, it will be a simple matter of search-and-replace to upgrade to the <nl>
form in XHTML 2:
<style type="text/css"> nl { list-style: none; margin-left: 0; padding-left: 0; } </style> ... <nl> <li><a href="/">Home</a></li> <li><a href="/about/">About</a></li> <li><a href="/news/">News</a></li> </nl>
There is one use of <br/>
which is legitimate and useful: marking up lines
of code, poetry, or anything else where explicit linebreaks are part of semantics
of the
content. For example,
<p class="program"> program helloworld(input, output);<br /> begin <br /> writeln("Hello world");<br /> end.<br /> </p>
In XHTML 2.0, this would become a sequence of l
(for "line") elements:
<p class="program"> <l>program p(input, output);</l> <l>begin</l> <l> writeln("Hello world");</l> <l>end.</l> </p>
There's not really a whole lot you can do to prepare yourself for this migration.
You could
theoretically wrap each line of code in an additional tag, like <span
class="line">...</span>
, to make search-and-replace easier when the time comes.
Whether this is worth the bandwidth -- both in human effort and in bits over the wire
-- is
up to you.
A Loss of Style
More Dive Into XML Columns |
|
The second major change in XHTML 2.0 is the loss of the inline style
attribute. Currently in XHTML 1, there are three different ways to style an element.
First,
define styles in a separate CSS file, and link to it in the <head>
section of your page. Second, define styles directly in the <head>
section of your page, with a <style type="text/css">
element. Third,
define styles directly on an element itself, with a style
attribute.
In XHTML 2.0, the first and second options will be available, but the third will not.
This
has been a relatively controversial decision, since inline styles on individual elements
are
very useful. But as Ian Hickson argues, the
style
attribute is mostly useful in situations where XHTML 2 is not meant to
be used, and it encourages the wrong behavior in general. He writes:
- It encourages a mindset that considers the visual media to be the most important one.
- It discourages the development of alternate stylesheets.
- It encourages a mindset that presentation is more important than semantics, which hurts accessibility.
- It allows authors to use the wrong semantic element and fix the error by changing the style inline, instead of picking the right element.
If you've been using the style attribute on documents that you want to migrate to XHTML 2, here are some possible strategies. All of these work now in XHTML 1 and will continue to work unchanged in XHTML 2.
-
ID attributes. Every element in XHTML (1 and 2) can have an
id
attribute which uniquely defines it within a document. You may already be using this if you're using scripting, but it's also useful for styling elements. If you're currently using a particular inline style just once within a page, give that element an ID attribute instead; then define CSS rules for that ID.For example, if your markup looks like this:
<p>Learning the <span style="font-variant: small-caps; font-weight: bold">ABC</span>s of markup is easy; the hard stuff comes later.</p>
You could enclose the style definition within the
<style>
which is within the<head>
of your document. Then simply use an ID attribute instead:<head> ... <style type="text/css"> #abc { font-variant: small-caps; font-weight: bold } </style> </head> <body> ... <p>Learning the <span id="abc">ABC</span>s of markup is easy; the hard stuff comes later.</p>
-
Class attributes. If you have multiple elements on a page that you want to style similarly, but there is no specific predefined element that is appropriate, use a
class
attribute. Expanding on our previous example, if your markup looks like this:<p>Learning the <span style="font-variant: small-caps; font-weight: bold">ABC</span>s of markup is easy; once you get to the <span style="font-variant: small-caps; font-weight: bold">XYZ</span>s, it gets more interesting.</p>
You can combine these styles and put
class
attributes on each similar phrase:<head> ... <style type="text/css"> .capword { font-variant: small-caps; font-weight: bold } </style> </head> <body> ... <p>Learning the <span class="capword">ABC</span>s of markup is easy; once you get to the <span class="capword"> XYZ</span>s, it gets more interesting.</p>
-
Multiple class attributes. Elements are not limited to a single class; you can define multiple classes, separated by spaces. This allows you to define more specific styles, and then mix and match as needed by defining multiple classes on each element. For example:
<p>Learning the <span style="font-variant: small-caps; font-weight: bold; background-color: transparent; color: red">ABC</span>s of markup is easy; once you get to the <span style="font-variant: small-caps; font-weight: bold; background-color: transparent; color: green">XYZ</span>s, it gets more interesting.</p>
Could become this:
<head> ... <style type="text/css"> .smallcaps { font-variant: small-caps } .bold { font-weight: bold } .red, .green { background-color: transparent; } .red { color: red } .green { color: green } </style> </head> <body> ... <p>Learning the <span class="smallcaps bold red">ABC</span> s of markup is easy; once you get to the <span class="smallcaps bold green">XYZ</span>s, it gets more interesting.</p>
Next month: the long, sad history of the <object>
element.