Category Archives: Style

StyleSheets, design and related issues.

The Cascade: Part 1

One of the most important yet, arguably, one of the least understood aspects of CSS is the cascade. Sure, most people will know that CSS stands for Cascading Style Sheets, but do you know what cascading really means and how it affects the way style sheets work?

From experience, I’ve seen many people struggle with specificity; often wondering why some particular rule isn’t applying and typically trying to work around it by adding id and class selectors to increase the specificity. While specificity is important to understand, it’s really only one step of the cascade; and so my aim today, and over the coming weeks, is to discuss cascading and inheritance as well as clearly explain the 4 steps of the cascade.

Style Sheet Origins

The cascade is designed around the combination of style sheets applying to a document, each coming from one of three origins, although authors typically only consider one: theirs! The three origins are the User Agent, User and Author. I’ll be talking more about the interaction of these in the next part, but for now, you just need to be aware that styles don’t just come from one place.

Step 1: Find Declarations

The first step in the cascade is to find all the style declarations that apply to each element, from all style sheets applied to the document, including style sheets from all three origins. This step involves collecting all the style declarations that apply for the target media type. This means, that if the document is being rendered on the screen, for example, any styles for the print media, or anything else for that matter, have already been discarded.

At this point, it doesn’t matter whether some selectors have a higher specificity than others or whether two rules set different values for the same property, or nearly anything else. The only factor is whether the selector matches the element or not.

For example, given the following stylesheets:

/* User Agent Stylesheet */
body { padding: 1em; margin: 0; line-height: 1.2em; }
p { margin: 1em 0; }

/* User Stylesheet */
body { font: large/1.4 sans-serif; }
* { background: blue none !important; color: white !important; }

/* Author Stylesheet */
html, body { margin: 0; padding: 0; background: #CCC; color: black; }
p { line-height: 1.4; }
#content p { margin: .8em 0; }

And this sample document:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<title>The Cascade</title>
<div id="content">
  <p>Hello World!
</div>

Find all the declarations that will apply to the p element. Before you continue reading, take a look and write down all the styles that you think will apply. This should be a fairly easy exercise, there’s no difficult selectors used at all; but even if there was, the concept would be exactly the same.

Assuming you attempted the excercie, you should have something like this:

p { margin: 1em 0; }
* { background: blue none !important; color: white !important; }
p { line-height: 1.4; }
#content p { margin: .8em 0; }

Now, this same process is repeated for each and every element in the document, but I’ll leave that as an exercise for the reader. In the next article in this series, we’ll talk about sorting by origin and importance, and then, later on, specificity and the order specified.

table-layout

Not to be confused with layout tables, this little used, yet wonderful CSS property ‘table-layout’ could have saved me a lot of time recently, had I thought of it. You see, the challenge I had was that I needed all columns of a table (containing tabular data) to be presented with equal width columns.

My immediate thought was to use col and specify widths in percentages. However, the difficulty was that the number of columns varied from 3 to 5 so I couldn’t just specify one single percentage, since the percentage would vary from approximately 33.3% for 3 columns to 20% for 5 columns.

Being a little rushed and not actually stopping to think, I decided that my only solution would be to specify a presentational class for the table element that indicated the number of columns, and then use that to select and style the col elements with the appropriate width. It wasn’t till a couple of days later that the better solution presented itself, which is ironic since I have, for about a week beforehand, been going over the CSS 2.1 tables module with a fine tooth comb, writing test cases for it and contributing them to the CSS 2.1 test suite.

The fixed table layout algorithm (CSS 2.1, section 17.5.2.1) defines in step 3:

Any remaining columns equally divide the remaining horizontal table space (minus borders or cell spacing).

Which means, if I hadn’t specified widths for any columns, nor any cell in the first row (as described in the rest of the algorithm), all the columns would be set to equal width. Oh, and by the way: Yes, this property is (miraculously) supported by IE! Now that I know how this property works, I’m sure I’ll be making a lot more use of it.