CSS Cascade and Specificity
CSS itself stands for Cascading Stylesheets, thus making cascade an important part of it. When multiple competing CSS rules could apply to an element, the browser has to choose which one to choose and how to control such selection.
The cascade algorithm defines ways to combine property values that have different origins. It determines which CSS rules matter and how CSS declarations with similar specificity are prioritised. In this blog, we have also used an example to understand the CSS cascade and specificity better.
What are the main stages of the Cascade algorithm?
To understand how the cascade algorithm and manner of browser resolving conflicts, it is essential to understand the four stages that the cascade algorithm is split in:
- Position and order of appearance: This signifies the order of appearance of CSS rules.
- Specificity: An algorithm to determine which particular selector has the strongest match amongst all available options
- Origin: This could be from either browser style, browser extension or authored CSS. Origin basically defines where CSS comes from.
- Importance: some CSS rules (such as the ‘important’ rule type) are weighted more heavily than others.
We will now understand each of these stages in more detail.
Position and order
In the cascade algorithm, if two rules have selectors of identical specificity, the selector declared last would be picked. Styles could come from link tags, embedded style tags and more.
For example, a CSS <link> at the top of an HTML page means another <link> will be at the bottom of the page. In such a case, the <link> at the bottom will have the maximum specificity. Similarly, embedded <style> elements become more specific as we go down the page. Inline style attributes with CSS declared, override all CSS unless another declaration has ‘!important’ defined. Position and order make an important aspect of the cascade algorithm.
Position is also declared in the CSS rule order, such as in case of the background being declared twice, the background colour declared last will be picked by the cascade.
Taking the example of font size, it depends on whether the browser supports clamp or not. In cases when it's declared twice and clamp() is supported, the previous declaration will be discarded; else, the initial one will be picked by the cascade algorithm.
The specificity algorithm determines the most specific CSS selector by using a weighting system. Making some particular rule more specific means using it despite some other CSS matches the selector appears later.
An important point to note is that CSS targeting a class on some element is more effective than CSS targeting the element alone to make a rule more specific.
Styles applied to 'id' override most of the other ones since 'id' increases specificity even more. In some cases, this can give a hard time overwriting such styles with something else.
Understanding specificity with code snippet:
<button class="branding"> Hey,
In the given example, there are 2 competing rules where different colors are declared. Now we will understand how CSS decides between competing rules.
CSS selectors should thus be as simple as possible and make the CSS easily reusable. Specificity is a great tool to get at elements. Still, it should be implemented after choosing from a long list of specific selectors, which will be explained in detail later in the article.
The Cascade considers the CSS written by the user and its origin, including browser stylesheet, styles added by the OS or browser extensions, and the user's authored CSS. Below is stated the order of specificity for these origins(most to least specific):
- User-agent styles with ‘!important’: All ‘!important’ defined by default and provided by the browser.
- Local user styles with ‘!important’: All ‘!important’ coming from browser extension level or the OS.
- Authored CSS with ‘!Important’: All ‘!important’ added to the user’s authored declarations.
- Authored CSS: CSS authored by the user.
- Local user styles: Styles from the OS like some base font size, or from browser extensions like the ones allowing user to create their own CSS for a page.
- User-agent base styles: Styles applied by the browser to HTML elements by default.
CSS rules have differing specificity and are not treated the same as each other.
The order of importance from most to least important for the cascade is listed below:
- ‘transition’ rule type
- ‘!important’ rule type
- ‘Animation’ rule type
- Normal rule type (eg: ‘font-size’, ‘background’, ‘colour’)
Every selector rule gets some scoring, and specificity could be understood to be the total score. All selector rules earn points towards this total score, i.e., specificity, and the highest score selector wins.
To prevent complexity in real projects, the specificity score must only be as high as necessary, rather than trying to achieve the highest score possible. This is because more important CSS might be needed in the future.
Scoring selector types
Since every selector type earns points individually, these points can be added up to find a selector's overall specificity. Let’s discuss each type of selector one by one:
A universal selector (*) gets 0 points and has no specificity, implying that rules with 1 or more points can override it.
Element or pseudo-element selector
This selector gets 1 point of specificity.
Class, pseudo-class or attribute selector
Any of these selectors get 10 specificity points.
The :not() is a pseudo-class and doesn’t add anything to the specificity calculation, but the selectors passed as arguments get added to the calculation for specificity
The above example has 11 specificity points since it has a type selector (div) and a class inside the :not() pseudo-class.
This gets 100 specificity points as long as an ID selector (#myID) is used, and not an attribute selector ([id="myID"]).
Inline style attribute
CSS directly applied to the HTML elements’ style attribute has a specificity score of 1,000 points. To override this, a highly specific selector is required.
|<div style="color: red"></div>|
‘!important’ style has 10,000 points for specificity score, the highest possible specificity of an individual item.
color: red !important; /* 10,000 points */
background: white; /* 10 points */
The specificity order is summed up below:
Frequently Asked Questions
What are the cascading rules in CSS?
The cascade in CSS assigns some weight to each style rule, and when several rules apply, the ones with the most weight take precedence. The rules in author stylesheets have more weight than user stylesheets by default.
What are the principles of Cascade?
In case of conflict among declarations, the cascade resolves it by considering the following things: Position, specificity, origin and importance.
What are the three parts of CSS syntax?
CSS syntax is a set of rules having three parts - a selector, a property and a value.
Which CSS selector and styles have the highest specificity?
The ID selector in CSS has the highest specificity, and In-line styles added to an element are considered to be the most specific.
In this article, we learned about the principles of CSS cascade, cascading rules and specificity of CSS selectors and styles using examples and code snippets.
You can take Coding Ninjas course to get started with the basics of web development in HTML, or visit CodeStudio to set your hand on Data Structures And Algorithms. Share this blog with your friends if you found it helpful! Until then, All the best for your future endeavours, and Keep Coding.
By Reet Maggo