Using XSL and CSS together

W3C Note 17 August 1998

This version
http://www.w3.org/Style/Plan/1998/08/NOTE-XSL-for-CSS-19980817.html
Latest version
(Not public yet)
Authors
Håkon Lie (howcome@w3.org), Bert Bos (bert@w3.org)

Status of this document

This document is [soon to be] a NOTE made available by the W3 Consortium for discussion only. This indicates no endorsement of its content, nor that the Consortium has, is, or will be allocating any resources to the issues addressed by the NOTE.

The note is published in the hope that it may provide a useful viewpoint for understanding the relation between various Web specifications. At this time (August 1998), work is being done in W3C on XSL and CSS, but the particular approach presented here is not currently on the charter of any working group. Discussion on whether it should be is invited.

Comments should be sent to the authors.

Abstract

This W3C Note describes how XSL [1] and CSS [2] can be used together. In particular, it discusses how XSL can be used as a bridge between complex XML-based documents and the CSS formatting model. It gives an outline of a system for displaying documents in XML-based formats as human-readable, or human-audible, text. To use the CSS properties in the language of XSL, it is necessary to invent an XSL-compatible syntax to represent CSS's properties. No new CSS properties, or other formatting semantics, is defined in this document.

Introduction

CSS is a powerful and easy to use formatting language. The two levels defined to date offer a wealth of formatting properties, and the next level promises to add even more. CSS is implemented by many programs and the experience from those implementations is being fed back into the development of more advanced formatting properties.

CSS, however, is only a formatting language. It lacks facilities commonly found in report generators, mail-merge programs, etc., for massaging a set of data into a human-readable format. It assumes that process has been done by an external program. In effect, that is how much of the information on the Web today is produced: information from a database at the server side is extracted and put into an HTML template, which is sent to a client (browser) and formatted and displayed.

With the advent of XML, the expectation is that in many cases the original data, rather than the HTML representation of it, will be sent to the client. This gives the client a richer data-set to work with, but CSS by itself may no longer be enough to transform it. XSL is designed to fill that gap.

Three ways to using XSL and CSS together suggest itself:

  1. Using XSL on the server to transform XML data into HTML documents with CSS style sheets. This has the benefit of being backwards compatible with a large number of User Agents.
  2. Using XSL to generate HTML/CSS on the client side. The content is passed through HTML/CSS to take advantage of current implementations, but is never made available in this form. This method required new functionality in User Agents.
  3. Transform directly to "CSS formatting objects". Compared to the previous method, this method is more direct as the content isn't converted to/from HTML. It requires new fuctionality in User Agents.

In the end, the latter might well be easier to use, as it requires only one language. But: it requires that CSS's formatting model be given an XSL syntax. This document shows how that might be done.

XSL basics

The language XSL is still under development. All syntax shown here is therefore tentative, and only meant to introduce the concepts.

The bulk of an XSL sheet is a series of pattern-action rules. The patterns are similar to CSS's selectors, but the action part may create an arbitrary number of "objects." An author of an XSL sheet selects a suitable set of objects and uses those inside XSL.

The set of objects could be anything for which a specification has been written; below we show how that specification might look for CSS. The objects need not be formatting objects: they could, e.g., be SMIL elements or RDF elements, once we write a specification for their syntax in XSL. In principle, when an XML syntax for a data-format already exists, it should be fairly easy to derive an XSL format from that.

The result of applying all matching patterns to a document recursively is a tree of objects. The conversion is one-way: given an object in the generated tree, it is, in general, impossible to run the conversion backwards to find the part of the source document that produced the object.

To give an example, the pattern-action rule below shows how one XML element ("partnumber") expands to a series of objects, with the content of the XML element expanded inside it ("process-children" indicates the place where the content of partnumber should be put):

<template match="partnumber">
  <css-object display="block"
              font-weight="bold"
              margin-top="20px">
    <css-object display="inline"
                color="red"
                content="Part number: "/>
    <css-object color="green">
      <process-children/>
    </css-object>
  </css-object> <!-- end of block -->
</template>

Declaring the CSS objects

As explained above, XSL is designed to be used with different sets of objects. The fo attribute at the top of the style sheet declares which set is in use. The identifier must have the syntax of a URL, so we might as well point it to something, e.g., this document:

<xsl fo="http://www.w3.org/TR/XSL-for-CSS">
  ... rest of sheet, with CSS objects...
</xsl>

Principles for creating the CSS objects

CSS doesn't have an XML syntax, which makes defining its XSL syntax slightly harder than it would be for, e.g., SMIL or MathML. Below are a few principles for the conversion, and some examples of the result.

CSS has properties like font and border, but also font-size and border-top, which allow small aspects of a font or border to be specified. The XSL syntax could either maintain this redundancy, or allow only one way to set a property.

CSS properties become XML attributes in the XSL syntax. Some CSS properties (font-family, content) accept both quoted strings and keywords. In the XSL syntax that would become font-family="'Times Roman', serif", which invites errors. Some possible ways to avoid double quoting are given below.

The main CSS object is simply called css-object. Some auxiliary objects may be necessary, either variants with extra functionality (e.g., css-anchor ), or objects to get around restrictions on XSL syntax (e.g., css-switch ). In principle, a css-object is the equivalent of the {...}-block of a normal CSS rule. For example:

{
  font-size: 10px;
  color: #FB9;
  text-indent: 1em
}

would become:

<css-object
  font-size="10px"
  color="#FB9"
  text-indent="1em">

Pseudo-classes

Pseudo-classes in CSS serve to select elements based on information other than what can be learned from their syntax in the source document. Examples are ":active," ":visited," and ":hover." One way to handle them is with a switch object (css-switch) that contains objects for all possible states, and let the renderer switch between the objects, based on the truth of some condition attached to them. For example:

<css-switch text-decoration="underline"
            background="red"
            font-style="italic">
  <css-object condition="active | hover"
              color="...">...</>
  <css-object condition="visited"
              color="...">...</>
</css-switch>

The css-switch object contains the properties common to the alternatives, and each alternative has a condition attribute that contains the condition under which this object is displayed. (A condition like "visited" also needs a way to indicate which URL is visited.)

Note that the "first-child" pseudo-class is handled by XSL's patterns directly.

Pseudo-elements

Pseudo-elements in CSS refer to parts of a displayed element, for which there is no (or cannot be) mark-up in the source document. ":Before" and ":after" are used to insert new elements where the source didn't have any, and ":first-letter" and ":first-line" refer to the first letter/line of a block box as actually displayed on the screen.

Since XSL templates allow an arbitrary number of objects to be created, the ":before" and ":after" are automatically catered for. The ":first-letter" and ":first-line" probably need something like the switch object above. For example:

<css-compound font="12pt Times"
              line-height="1.2"
              text-align="left">
  <css-first-line font-variant="small-caps"
                  color="green"/>
  <process-children/>
</css-compound>

The css-compound object is like css-object, but it may have two special children, css-first-line and css-first-letter, that hold the properties of the pseudo-elements.

Page box

For paged media, CSS2 allows the characteristics of the pages to be described with @-rules. Since XSL has no place for global declarations, the best place to put them is probably near the root of the generated object tree. An @page-rule might translate to a css-page object:

<template match="/">
  <css-page size="landscape"
            margin="1.5in 1in"
            marks="crop"/>
  <css-page name="left"
            .../>
  <css-page name="rotated"
            .../>
</template>

Media types

Selection of output medium could be handled outside of XSL, like it is for CSS level 1. That means that to write an XSL sheet for two media, say print and screen, one has to write two sheets. They could still import a sheet with common rules.

Web-fonts

Another @-rule in CSS is the one for defining Web-fonts. These, again, should probably become objects that are attached close to the root of the object tree:

<template match="/">
  <css-font font-family="Pantani"
            panose1="4726402695"
            font-style="all" />
</template>

Replaced elements

Replaced elements could be handled with a css-replaced object, which has the combined attributes of the css-object and the object element from HTML:

<css-replaced src="/Icons/w3c_home.png"
              type="image/png"
              params="..."
              border="solid red"
              .../>

Interactive elements

Hyperlink source anchors and form elements have not only style, but also a behavior when a user activates them. In CSS that behavior doesn't need to be specified, since the displayed boxes on the screen have a direct link to elements in the source, and those elements come with their own semantics. Because of the transformation that takes place in XSL templates, that back-link is not available, and the transformation needs to carry any behaviour information forward from the source elements to the generated objects. How this can best be done is still an open issue. Introducing ojects like css-anchor (like css-object, but with an extra href attribute), and css-form, css-input, etc. may be a solution.

Counters & the content property

To make the syntax slightly easier to read, it may be possible to make counters into css-counter objects. If some escaping of whitespace is accepted, the content property could be discarded altogether, making quotes inside quotes no longer necessary:

<template>
  <css-object>Figure&#32;</> <!-- 32=space -->
  <css-counter name="figno" style="upper-alpha"
               font-weight="bold"
               color="blue"/>
  <css-object>.&#32;</css-object>
  <process-children/>
</template>

The attr() function could be handled analogously.

Other string-valued properties

Font-family is another property that uses a mixture of quoted strings and keywords. It could be split into two. That would make the inheritance model different, but avoid quotes inside quotes:

<css-object font-family="helvetica, gill sans"
            generic-font-family="sans-serif">...</>

text-align also accepts string; a similar split might be possible.

Convenience

It may be useful to add convenience objects ("syntactic sugar"), such as an object for horizontal rules, which is just a shorthand for a css-object with certain properties, or a css-block , which is just a css-object with the display property set to block.

References

[1] Extensible Style Language, XSL, is under development within W3C. Current plans indicate that XSL will become a W3C Proposed Recommendation in the middle of 1999.

[2] Cascading Style Sheets, CSS, is defined in two W3C Recommendations, Level 1 (http://www.w3.org/TR/REC-CSS1) and Level 2 (http://www.w3.org/TR/REC-CSS2).