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.
When are the rest of the parts slated?
Still on the todo list 🙂 I’ll try and get part 2 out this month.