Just announced on www-style, was the news that Prince now passes Acid 2. They’re the 4th, after Safari, Konqueror and iCab. They’re also the first non-browser implementation to pass. Well done!
Category Archives: Style
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.