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.