This week I was debugging an issue with the CSS of the application we are building at a client. It turned out that the CSS was applied to the document in an order that I wasn't expecting. It's about time for me to learn how CSS is applied to HTML documents.
Before we have a look at how the CSS is applied to a page, the CSS needs to be loaded first. This happens in the following way.
1) First, the Browser loads an HTML file
2) The HTML file is converted to the Document Object Model (DOM)
4) The browser parses the CSS and applies the style
5) A render tree is created
6) Lastly, the page is displayed
There are two important ways that CSS is applied to a page, its cascading order and the specificity.
The CSS that is applied to a page can come from different origins. The cascading order determines what origin to apply first.
There are 3 different origins the CSS can come from:
- User-Agent; These style sheets come from the browser and can be real style sheets or hardcoded values.
- Author; These are the most common style sheets, the style sheets that are added to a website.
- User; It's possible for users to override the style sheets and customize the look.
The order in which the origins are applied is:
Note that later defined styles within the same origin win.
Another thing that you need to keep in mind is animations. The
@keyframes rules work a little bit different. They don't cascade and don't mix together. If multiple
@keyframes are defined, the last one is chosen.
Within the cascading of origins, the specificity of the CSS is used.
The specificity is calculated by adding weights to the different declarations:
- 0 for
- 1 for elements (
div) and pseudo-elements (
- 10 for classes (
[some-attrib]) and pseudo-classes (
- 100 for IDs (
- 1000 for inline styles (
Of course in CSS these will be combined which means the values are added together.
A few examples:
If we have a look at the following CSS, a few things happen there:
The text on a div with the ID
some-id will be red. This is because line 1 calculates to 101 (an ID and an Element). The second line only calculates to 100, the last one calculates to 11 (and element and an attribute).
Now assume we have an
H1 on the page. Without a class, this will become purple. Because the latest defined rule wins. If we would add a class (
some-class) the text becomes yellow, a class is more specific than the element.
I think I get it now :)