Comparing CSS and XSL: A Reply from Norm Walsh

February 9, 2005

Norman Walsh

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">


    <xsl:if test="not(preceding-sibling::html:li)">

      <xsl:attribute name="keep-with-next">always</xsl:attribute>



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">


    <xsl:if test="not(preceding-sibling::x:listitem)">

      <xsl:attribute name="keep-with-next">always</xsl:attribute>



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">






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":

  1. :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?

  2. 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?

  3. normal? What on earth does normal mean in this context?

  4. 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=""




  <xsl:import href=""/>

  <xsl:template match="html:h1|html:h2|html:h3|html:h4|html:h5">

    <fo:block keep-with-next="always">





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.

Sample output
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.


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.