Comparing CSS and XSL: A Reply from Norm Walsh
by Norman Walsh
February 09, 2005
In
Printing
XML: Why CSS Is Better than XSL, Håkon Wium Lie and
Michael Day launch an aggressive attack on
my
assertion that "web
browsers suck at printing" and "CSS is never going to fix it." In
retrospect, I regret the way that I expressed that. I suppose the
shortest possible reply to their article would simply be "I was wrong.
Cool!" For simple HTML documents, CSS can produce reasonable-looking print output. (Printing from web browsers still sucks, and I
don't see any evidence that that's going to change in the near future,
at least not
for the web browsers with the largest market share.)
Lie and
Day use my casual remark as
a springboard for a more general discussion of why
CSS is better than XSL. As active developers of the
CSS specifications, I'm hardly surprised, especially since they've
covered this ground before.
I've covered this ground before too; I've been involved in XSL
from the beginning. I don't believe that XSL is
better than CSS and I never have. I think it's great that CSS has
developed the ability to produce reasonable pages with running headers
and footers and multiple columns. I can't see how to extend it to
support multiple flow regions, back of the book indexes, change bars,
or some of the other features in
XSL 1.1,
nor can I see how to
produce print output from source XML manuscripts, in general, without
the transformational power of XSLT. But, as we've just seen, I've been
wrong before.
However, with respect to some of the points made in their
article, I maintain that they are, if not actually incorrect, at least
misleading. To a certain extent, this depends on whether you interpret
their article as simply a criticism of the
Extensible Stylesheet
Language (XSL FO) or if their argument is
that CSS should replace both
XSL Transformations (XSLT)
and XSL FO. I don't find that completely
clear in their article. In this rebuttal, I've tried to
demonstrate that XSL FO is not, in fact, as bad as they would have you
believe. In general, there are lots of places where
you will want to transform with XSLT and then use CSS
for presentation, and I never meant to imply that that wasn't the
case.
On Syntax
What is the substance of their argument that CSS is
better than XSL? It seems to boil down to "which do you find more
readable?" That's an important consideration, but readability,
in terms of eyeballs on source code, is only one aspect
of ease of understanding. One of the fundamental virtues of XSL (both XSLT
and XSL FO) is that they're expressed in XML and therefore inherently
accessible to machine processing and
machine validation.
I use CSS on almost every web page I write or generate these
days. It's absolutely the best way to provide styling for web content.
However, I often struggle with its irregular syntax. On more occasions
than I'd care to recall, I've wasted time trying to track down a
styling issue that ended up being a missing semicolon or curly brace
somewhere.
(I do wish browsers would actually report syntactic errors in CSS.)
I'd prefer an XML expression of CSS, but I expect
that would be a controversy of another kind.
The extent to which one likes or dislikes a particular syntax
seems to rest in part on personal convictions and artistic
sensibilities. Some folks really seem to dislike angle brackets and
the syntactic constraints of XML. I'm not one of them.
On Simplicity
One of the comparisons that Lie and Day make is between my template for list
items and theirs. I've got:
<xsl:template match="html:ol/html:li">
<fo:list-item>
<xsl:if test="not(preceding-sibling::html:li)">
<xsl:attribute name="keep-with-next">always</xsl:attribute>
</xsl:if>
...
They've got:
ol li:first-of-type { page-break-after: avoid }
They argue that that's "intuitive." I try to stay away from words
like intuitive when it comes to technology, but in any event, they're cheating
a little. They're relying quite a bit on the semantics of HTML elements. Suppose
the source document was written in terms of x:orderedlist and x:listitem elements.
Then I think they'd need something more like this:
x|orderedlist { display: block;
list-style-type: decimal;
margin-left: 2em;
margin-top: 1em;
}
x|listitem { display: list-item
}
x|orderedlist x|listitem:first-of-type
{ page-break-after: avoid
}
It's arguably still syntactically simpler, but I think it might be a stretch
to call it "intuitive," especially with the struggle to fit namespaces
into selectors.
The only change needed in the XSLT, by the way, is this:
<xsl:template match="x:orderedlist/x:listitem">
<fo:list-item>
<xsl:if test="not(preceding-sibling::x:listitem)">
<xsl:attribute name="keep-with-next">always</xsl:attribute>
</xsl:if>
...
This amounts to a total change of three QNames. And, in fact, if I'd known I was going to
be judged on the basis of intuitive understanding, I probably would have broken
things into smaller, simpler templates without the explicit conditional.
Even with the more complex CSS I've written above, it's still not really an
apples-to-apples comparison. The XSLT fragment above is part of a program that
transforms HTML into the presentation vocabulary. This transformation can do
arbitrarily complex tasks: sorting and grouping content, formatting structured
datatypes such as times and dates in a variety of ways, merging documents,
profiling content based on a arbitrary set of criteria, text and image transclusion,
even accessing external databases and other information sources with a little
extension. I don't believe there are general solutions to these problems in
CSS.
The CSS rules above, for x|orderedlist and x|listitem,
would be more directly compared to the XSL FO fragment:
<fo:list-block margin-left="2em" margin-top="1em">
<fo:list-item keep-with-next="always">
<fo:list-item-label>...</fo:list-item-label>
<fo:list-item-body>...</fo:list-item-body>
</fo:list-item>
...
</fo:list-block>
A list, as you can see, is simply a block containing items where each item
has a label and a body. It's hardly the paragon of complexity that you might have
been led to imagine. And this same straightforward structure is used to express
all of the various sorts of lists.
On Generality
Lie and Day go on to suggest that CSS is somehow superior to XSL because it
has a builtin definition for the size of "A4" paper. In particular,
they find the template that maps page sizes to physical dimensions "entertaining."
They "do not understand why this list belongs in a stylesheet." It
belongs in a stylesheet for two reasons: first, because the stylesheet author
is ultimately responsible for the design of the resulting document and may
therefore wish to exert some control over the page sizes, and second, because
there's no reason why users shouldn't be able to treat specialty sizes in the
same way that they treat all the other sizes.
That template exists not because it was necessary but because I wanted to
make it easy for someone in Europe, for example, to select A4 paper. I could
just as easily let them choose "corporate-standard" paper or "googledy-froogledy" paper,
if I wished.
Surely specifying "paper.type='A4'" for the XSLT processor is
as simple as writing a new stylesheet and adding it to the CSS cascade to override
the A4 setting that Lie and Day have hard coded.
In fact, a fair number of the templates in my stylesheet were adapted from
the DocBook XSL stylesheets where we're trying to give a lot of flexibility
to designers extending the base stylesheets.
On the subject of page numbers, we find the assertion that "while not
pure English prose, [these statements] are easily understandable for anyone
who has read this far." Those statements include:
@page :first {
@bottom-right {
content: normal;
}
}
About which I have a few questions that seem far from "easily understandable":
-
:first? First in the document or first in this
page sequence? Or does CSS not have the notion of page sequences that allow,
for example, separating content into front, body, and back matter for different
layouts?
-
bottom-right? On the right-hand side of the
physical page or on the ending side according to the writing direction
of the document? On the physical bottom or at the end of the page in whatever
direction it is being filled?
-
normal? What on earth does normal mean in this
context?
-
Not shown above, but given as an option in a nearby example in their paper,
is counter(page). What typographic treatment
does the page number get? Is it arabic, roman, or something else?
I'm sure the answers are clearly spelled out in the CSS specification, just
as the answers to similar questions are spelled out in the XSL specification.
My point is simply that CSS is no more or less "understandable" in
any deep sense without reading the specification than any other piece of technology
more complex than a rock.
On Reuse
It's hard to express an apples-to-apples comparison of the reuse features
in CSS and XSL. On the one hand, XSL FO documents offer relatively little in
terms of reuse. There's nothing at that level that corresponds to the CSS "cascade."
On the other hand, XSL FO documents are often generated, as is the case for
the essay I published originally, from XSLT stylesheets.
XSLT stylesheets have a rich model for importing, including, and otherwise
reusing elements of another stylesheet. XSLT 2.0 relaxes a few inconvenient
constraints in XSLT 1.0 and will make this sort of extension even easier.
To take the page break example from their paper, suppose that I had neglected
to specify in my stylesheet that all the headings should prevent page breaks
from occurring before the following block. I could easily add that with the
following stylesheet which imports all of the functionality of my original:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:html="http://www.w3.org/1999/xhtml"
version='1.0'>
<xsl:import href="http://www.w3.org/2001/tag/webarch/html2fo.xsl"/>
<xsl:template match="html:h4|html:h4|html:h4|html:h4|html:h5">
<fo:block keep-with-next="always">
<xsl:apply-imports/>
</fo:block>
</xsl:template>
</xsl:stylesheet>
That seems no more complicated than the CSS equivalent. At the same time,
having a hook into a real transformation language means I could equally have
done a much more extensive transformation.
For example, suppose you wanted to introduce each section with an indication
of where it was referenced in the document. We can easily extend the functionality
of the XSL FO stylesheet to incorporate this behavior as well. The resulting
stylesheet is a little more complicated than the example above, but it's
doing a bit more work as well.
An example of the result of this stylesheet is shown in Figure 1, Output
with References.

Figure 1. Output with References
The ability to extend and reuse stylesheets that transform documents to XSL
FO offers much greater flexibility than simply changing the properties and
the values as CSS provides.
Conclusions
If you can satisfy all of your online and print publishing
requirements with CSS, by all means do so. CSS is clearly more capable
than I gave it credit for, and it may provide sufficient functionality to
satisfy a wide range of publication needs.
In fact, my first attempt at producing a reasonable printed
version of the web
architecture document was to fiddle with the CSS. It was only
when that failed to have any significant influence on the browsers
I was using that I resorted to crafting the XSL FO stylesheet.
I'm certain that a great deal of the XML content out there will
need to be transformed in one way or another before it is presented
and that the natural tool to perform this transformation will be XSLT.
To the extent that there are features available in XSL that aren't
available in CSS, I don't find the arguments made by
Lie and Day about CSS's inherent simplicity,
generality, or reusability at all persuasive.
But at least we can agree that red herring
about
semantics is a different discussion.