CSS Cascading and Specificity
This article will focus on the details of how the CSS properties get applied to the HTML elements.
Cascade means “A succession of stages” and that is how the style declarations are applied to the HTML documents. A style declaration cascade down to document elements from many origins or statges.
Why cascading is that important?
For big websites, normally there are more than one ways of style declarations, more than one stylesheets and more than one type of stylesheets or simply more than one origins of stylesheets. Due to the requirements or mistakes these declarations often conflicts with each other and produces some unexpected results. For example
1 2 3 4 5 6 7 | <style> #container .spanClass{display:block;border:1px solid red;} #container span{display:block;border:1px solid black;} span{display:block;border:1px solid green;} .spanClass{display:block;1px solid yellow} </style> <div id='container'><span class='spanClass'></span></div> |
in the above example all the four declaration assign styles to the same span elements. All the declaration are setting the display property to block. So its not going to create any problems, at least for now. But the border color is different in all the declarations. Which color will be assigned to the border of the span element? These conflicts can be solved only with knowledge of cascading.
How it works?
Cascading takes the following into consideration before answering the big question, which declaration?
1. Importance
2. Origin
3. Specificity
4. Source order
The process of resolution employed by the CSS cascade involves four steps:
1. For a given property, find all declarations that apply to a specific element.
2. Sort the declarations according to their levels of importance, and origins.
3. Sort declarations with the same level of importance and origin by selector specificity.
4. Finally, if declarations have the same level of importance, origin, and specificity, sort them by the order in which they’re specified; the last declaration wins.
Let us look into each step a bit more deeper
In step one, a user agent looks into all the sources for all the valid declarations for the specific property to be applied to the element in question. There are three types of sources : the user agent, the author, and user style sheets.
User agent style sheets :- are the default sets of declarations applied by the user agent.
User Style Sheets :- Some user agents [Opera, Safari] allow a user to create a customized set of styles to use by default, or for specific documents.
Author style sheets :- are those that are linked to the document via a link element, specified using a style element within the document’s head element, or specified within an element style attribute (inline styles).
The user agent must search through all the sources until it has all the style declarations that are available for the property, and applicable to the element in question. If there’s more than one applicable declaration that sets a specific property on an element, the cascade proceeds to step two.
In step two, declarations that set the same property for the same element are sorted by their levels of importance, and their origins. A declaration can have either of two levels of importance:
1. declarations that are appended with the !important statement are called important declarations;
2. declarations that aren’t are called normal declarations.
Declarations are sorted in the following order (from lowest to highest priority):
1. user agent declarations
2. normal declarations in user style sheets
3. normal declarations in author style sheets
4. important declarations in author style sheets
5. important declarations in user style sheets
The declaration with the highest priority is applied to the element. If two or more declarations that have the same priority , the cascade proceeds to step three.
In step three, declarations are sorted on the basis of the specificity of their selectors.
The concept of specificity states that when two or more declarations that apply to the same element, and set the same property, have the same importance and origin, the declaration with the most specific selector will take precedence.
Rules For calculating Specificity
1. If one declaration is from a style attribute, rather than a rule with a selector (an inline style), it has the highest specificity. If none of the declarations are inline, proceed to step two.
2. Count the ID selectors. The declaration with the highest count has the highest specificity. If two or more have the same number of ID selectors, or they all have zero ID selectors, proceed to step three.
3. Count the class selectors ( .adsClass), attribute selectors ([type="submit"]), and pseudo-classes ( :hover). The declaration with the highest total has the highest specificity. If two or more have the same total, or they all have totals of zero, proceed to step four.
4. Count the element type selectors (div, span, p) and pseudo-elements (:first-letter). The declaration with the highest total has the highest specificity. If two or more selectors have the same specificity, then, according to the rules of the CSS cascade, the latter specified rule takes precedence.
So In simple terms here is the precedence order highest to lowest
1. Inline Style
2. Ids
3. Classes, Attributes, and Pseudo-classes
4. Element Types and Pseudo-elements
The specificity of a selector is represented by four comma-separated values, and is calculated by counting the occurrences of different elements in the selector.
(Inline Style ), (Ids), (Classes, Attributes, and Pseudo-classes), (Element Types and Pseudo-elements)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <body id='home'> <div id='mainwrapper'> <p class='notice'> Some Text ... </p> </div> </body> p.notice { color: green; } #home #mainwrapper p.notice { color: yellow; } #mainwrapper p.notice { color: white; } body#home div#mainwrapper p.notice{ color: blue; } p { color: teal; } * body#home>div#mainwrapper p. notice{ color: red; } #mainwrapper p { color: black; } |
In the above example none of the declaration are inline.
So as per the specificity rule all the declarations have been ordered according to specificity—the highest are at the top,
1 2 3 4 5 6 7 | body#home div#mainwrapper p.notice (0, 2, 1, 3) * body#home>div#mainwrapper p. notice (0, 2, 1, 3) #home #mainwrapper p.notice (0, 2, 1, 1) #mainwrapper p.notice (0, 1, 1. 1) #mainwrapper p (0, 1, 0, 1) p.notice (0, 0, 1, 1) p (0, 0, 0, 1) |
The declaration that has the selector with the highest specificity is applied to the element. However, if two or more declarations that set the same property for the same element also have the same levels of priority and specificity as in the example above, the CSS cascade proceeds to step four.
Step four is the simplest step and makes the final determination about which declaration to apply to the element without ambiguity. The declaration that’s specified last is the one that’s applied to the element—a process that’s often expressed as the latter declaration overwriting the former. A declaration can be overwritten by another within the same declaration block, within the same style sheet, or in another style sheet.
Now we know how to overwrite CSS declaration to fit the new requirements without affecting the previous settings.
Discussion 6 Responses
Leave a Reply