Free Trial

Safari Books Online is a digital library providing on-demand subscription access to thousands of learning resources.

  • Create BookmarkCreate Bookmark
  • Create Note or TagCreate Note or Tag
  • PrintPrint

4.2. An Overview of CSS

This section takes a quick look at the major CSS topics.

4.2.1. Declaring the Stylesheet

To associate a stylesheet with your document, you need to declare it at the beginning so that the XML processor knows which stylesheet to use and where it's located. This is usually done with a processing instruction whose syntax is shown in Figure 4.5. Like all processing instructions, it will be ignored by any XML processors that don't need or recognize stylesheets. In this section, we discuss the subset of processors that actually transform XML into another format using stylesheets, such as web browsers that can format XML into a nice-looking page.

Figure 4.5. Syntax for a stylesheet declaration


The declaration begins with the processing instruction delimiter and target <?xml-stylesheet (1). The PI includes two property assignments similar to attributes. The first property, type (2), is set to the MIME type (3) of the stylesheet (for CSS, this is text/css). The value of the other property, href (4), is the URL of the stylesheet (5), which can be on the same system or anywhere on the Internet. The declaration ends with the closing delimiter (6).

Here's how it is used in a document:

<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="bookStyle.css"?>
<book>
  <title>Tom Swift's Aerial Adventures</title>

  <chapter>
    <title>The Dirigible</title>
  ...

4.2.2. Combining Multiple Stylesheets

A very powerful feature of CSS is its ability to combine multiple stylesheets by importing one into another. This lets you borrow predefined style definitions so you don't have to continuously reinvent the wheel. Any style settings that you want to redefine or don't need can be overridden in the local stylesheet.

One reason to combine stylesheets is modularity. It may be more manageable to break up a large stylesheet into several smaller files. For example, we could store all the styles pertaining to math equations in math.css and all the styles for regular text in text.css. The command @import links the current stylesheet to another and causes the style settings in the target to be imported:

@import url(http://www.mycompany.org/mystyles/math.css);
@import url(http://www.mycompany.org/mystyles/text.css);

More stylesheet stuff...

Some of the imported style rules may not suit your taste, or they may not fit the presentation. You can override those rules by redefining them in your own stylesheet. Here, we've decided that the rule for <h1> elements defined in text.css needs to be changed:

@import url(http://www.mycompany.org/mystyles/text.css);

h1: { font-size: 3em; }    /* redefinition */

4.2.3. How Stylesheets Work

The following sections explain CSS stylesheets in more detail.

4.2.3.1. Matching properties to elements

A CSS stylesheet is a collection of rules. Each rule contains style settings to be used on a particular element type. The CSS processor (a program that converts XML into a formatted document using a CSS stylesheet) goes through the XML document one element at a time, tries to find the best possible rule to apply to it, and builds a picture.

An analogy for this process is painting-by-numbers. In this activity, you purchase a painting kit that comes with paints, a brush, and a canvas on which the outlines of color regions have been drawn. Each region has a number that corresponds to a paint color. Do your best to color within the lines and eventually you'll have a stylized rendering of a pastoral scene with cows and an old barn. The regions to color are like elements in an XML document. The paint cans with numbers on them are like stylesheet rules.

The process is like this:

  1. Pick the next unpainted region to color.

  2. Find the paint can that matches the number in the region.

  3. Fill in the region with that paint.

  4. Repeat until you run out of unpainted regions.

The process with CSS is similar:

  1. Pick the next element to format.

  2. Find the rule or rules that best match the element.

  3. Use the style settings in the rule(s) to format the element.

  4. Repeat until you run out of unformatted elements.

Each rule has two parts: a selector, which matches rules to elements, and a properties declaration, which contains style settings. A CSS rule looks like this:

sidebar { 
  border: thin gray solid;
  padding: 10pt;
}

Qualitatively, it would be like saying, "For all <sidebar> elements, surround the region with a thin, gray border, and indent the text on all sides by 10 points." The selector matches any <sidebar> element, and the declaration contains two properties: border and padding.

4.2.3.2. Rule conflict resolution

As we said before, the CSS processor tries to find the best rule (or rules) for each element. In a stylesheet, there may be several rules that apply. For example:

p.big { 
  font-size: 18pt; 
}

p { 
  font-family: garamond, serif;
  font-size: 12pt;
}

* { 
  color: black;
  font-size: 10pt; 
}

Suppose the next element to process is a <p> with the attribute class="big". All three rules match this element. How does CSS decide which properties to apply?

The solution to this dilemma has two parts. The first is that all rules that match are used. It's as if the property declarations for all the applicable rules were merged into one set. That means all of these properties potentially apply to the element:

font-size: 18pt; 
font-family: garamond, serif;
font-size: 12pt;
color: black;
font-size: 10pt;

The second part is that redundant property settings are resolved according to an algorithm. As you can see, there are three different font-size property settings. Only one of the settings can be used, so the CSS processor has to weed out the worst two using a property clash resolution system. As a rule of thumb, you can assume that the property from the rule with the most specific selector will win out. The first font-size property originates from the rule with selector p.big, which is more descriptive than p or *, so it's the winner.

The properties that apply to the current element are now:

font-size: 18pt;
font-family: garamond, serif;
color: black;

4.2.3.3. Property inheritance

In XML documents, there is a hierarchy of elements. CSS uses that hierarchy to pass along properties in a process called inheritance. Going back to our DocBook example, a <sect1> contains a <para>. Consider the following stylesheet:

sect1 {
  margin-left: 25pt;
  margin-right: 25pt;
  font-size: 18pt;
}

para {
  margin-top: 10pt;
  margin-bottom: 10pt;
  font-size: 12pt;
}

The <para>'s set of properties is a combination of those it explicitly declares and those it inherits from the elements in its ancestry (not counting those that are redefined along the way). And here, it has inherited the properties margin-left and margin-right from the <sect1> element. It does not inherit font-size from <sect1> because that property is explicitly declared by the <para>, in effect eclipsing the earlier declaration.

4.2.3.4. Comments

Just as XML lets you insert comments that are ignored by the XML processor, CSS has its own comment syntax. A comment starts with the delimiter /* and ends with the delimiter */. It can span multiple lines and enclose CSS rules to remove them from consideration:

/* this part will be ignored
gurble { color: red }
burgle { color: blue; font-size: 12pt; }
*/

4.2.4. CSS Limitations

Although CSS is good enough for many rendering tasks, its simplicity can be a limitation for more complex formatting. One major problem is that the order in which elements are processed can't be changed. Consider the following piece of XML:

<figure>
  <title>The Norwegian Ridgeback Dragon</title>
  <graphic fileref="nr_dragon.png"/>
</figure>

In CSS, elements are processed in the order of their appearance in the XML document. So in this example, the figure's title will be rendered before the graphic. Although a template-based stylesheet language like XSL would be able to place the title below the graphic, CSS can't.

Since CSS can't create any kind of structure other than that of the XML source file, there are many kinds of presentation that you can't do. For example, you can't generate a table of contents by finding every header element in the document and assembling them into a list. For that, you need a language like XSLT, which has the power of XPath to collect nodes and process them in any order.

The CSS selector syntax is limited to element names, attributes, and element context. This isn't enough information for some tasks. Sometimes, you need to perform arithmetic on element positions and values. You may need to make logic judgments: "If this element has no children, then color it green; otherwise color it red." You might need to follow links and see what's on the other side. For such sophisticated processing, CSS doesn't have the muscle; you need to move up to XSLT.

For the purpose of seeing how stylesheets work on a basic level, we can live with these limitations. But in Chapter 6, we'll jump to a higher level of stylesheet expressiveness, and you'll see a huge difference in what you can do.

  • Safari Books Online
  • Create BookmarkCreate Bookmark
  • Create Note or TagCreate Note or Tag
  • PrintPrint