In this article, I will explain how CSS conflicts are resolved automatically in the browser, what are the concepts for solving issues with contradicting declarations and how to quickly override the default behavior.
Do you prefer video?
There are three possible places where you can have your CSS styles defined.
First, it can be inside the <head> element of the HTML document you want to style. In such case, you need to wrap your stylesheet with the <style> element.
Second, it can be right inside the specific HTML tag. In such case, you need to have your style defined as a value of the style argument of that HTML tag. This is not very useful for big stylesheets.
Third, it can be stored in a separate file which is linked to the HTML document you want to style. In such case, you use the <link> element placed inside the <head> element.
But what would happen if you had two or three styles defined for the same document and they contradict each other?
You can have a CSS rule inside the external file which defines the color of the <p> element as yellow, but at the same time you can have another CSS rule which defines color as red right inside the <p> element.
What would happen? What would be the color? Yellow or red? That’s what we are about to find out now.
Download the css-conflicts.zip to the location of your choice, unpack the archive and open the css-conflicts.html file in the code editor. In this file, there are three definitions of the style for the <p> element.
The first one is inside the attached style.css file and it says that the color should be yellow. The second one is inside the <head> element and it says that the color should be blue. And finally, we have a third style as an attribute of the <p> element itself which says that the color should be red.
Now, open the file in the browser to see which color wins. As you can see the color of the text is red, but why?
There are rules that define the priority of application of styles in case of conflicting definitions. It’s in the name of CSS, cascading.
Cascading is the fundamental feature of CSS. It defines how CSS rules from different sources are propagated. Cascading algorithm decides which declaration is applied to any given element and thus solves potential conflicts between declarations.
There are four concepts for solving issues with contradicting declarations and rules:
Let’s look at each of them now.
The origin precedence rule states that if declarations are in conflict, then the last declaration wins over the previous declarations.
That means the declaration which is the last one in the code. Since HTML is processed sequentially from top to bottom, the bottom-most declaration overrides all the declarations above it.
In case of external CSS file, its position in the document is where the link is placed. Think of it as if the whole content of the linked file is inserted instead of the link, thus the whole stylesheet would be a part of the HTML document.
When declarations are not in conflict, they just merge into one big declaration and all properties are applied.
In the css-conflicts.html file, add the font-weight declaration to the style for the <p> element placed in the <style> element of the document:
Also, go to the style.css file and set the background-color to yellow:
Save the changes and refresh the page in the browser. You will see the bold red text on the yellow background.
Even though the conflicting text color declarations have been resolved by applying the last declaration, the rest has been merged together.
So, we have the background color defined in the external style.css file, bold text defined in the internal stylesheet inside the <style> element of the document and the text color defined directly inside the <p> element.
To see it in action, just right click the paragraph and select Inspect option to open Chrome Developer Tools in the browser.
Here, you can see the list of styles applied to the paragraph element along their origin and even which style wasn’t applied because it was overridden by another style:
If you specify a property for an element, all its descendants will inherit that property.
But how could the browser know about the descendants of a specific element? That’s where the DOM, or Document Object Model comes in the scene.
The DOM is an interface that treats HTML document as a tree structure. Each node of this tree is an object that represents a part of the document.
Most web browsers use the internal document object model to render HTML documents. The browser downloads HTML document into local memory and parses it to display the page on the screen.
Once the browser knows which element is a child and which element is a parent, it’s easy to apply the Inheritance concept on HTML elements.
You can see the example of DOM tree at the image below:
Don’t confuse DOM with BOM. While DOM deals with the HTML elements,
the BOM (Browser Object Model) deals with browser components, such as
history, location, navigator, screen, and so on.
Open the css-inheritance.html file in the browser and select Inspect to display Developer Tools.
As you can see, we have a style defined for the <body> element. This style will be inherited by both <p> elements except for the color of the text of the first <p> element which is directly specified for it as an inline declaration.
The <h1> element will inherit everything from the <body> element. We didn’t have to specify any style for the <h1> element, yet it is styled thanks to the inheritance.
Specificity concept is based on the rule that the most specific selector combination wins. Selectors have different scores and the highest total score of selectors (or their combinations) wins.
The highest score is 1000 and we will get it if we specify the style directly inside the tag with inline stylesheet:
The lowest score is 0001 which we will get if we define the style for an element. If there are two elements combined, we will get the score 0002, because it has higher specificity:
Let’s try to calculate the score for these two examples to see what color will be assigned to the paragraph:
In the first example, we have the element selector (div) and the id selector (#paragraph). So, the style gets 0 points, the id gets 1 point, there’s no class, pseudo-class or attribute, so this gets 0 points as well. Finally, the number of affected elements is 1 because there’s only the div element in the definition.
In the second example, we have the element-class combinator (div.green) and the element selector (p). So, the style gets 0 points again, the id gets 0 points as well, but there’s one class, so this gets 1 point. Finally, we have two elements affected, the div element and the p element, so this gets 2 points.
Based on the calculation, the color of the paragraph should be blue, because the definition for the blue color gets 101 points, while the other definition for the green color gets only 12 points.
Once you have this done, open the css-specificity.html file to see the result. And sure enough, the color of the paragraph is blue indeed.
Sometimes, we don’t have time to calculate the score or think about what declaration wins and why. In such cases, the !important rule might be helpful.
Add a new CSS declaration to your css-specificity.html file right above the closing part of the </style> tag:
Even though this is the least specific selector, it doesn’t matter because it will be applied anyway.
Save the changes and refresh the page in the browser to see that the text color of the paragraph will change to red.
I strongly suggest against using the !important rule though, because it will only add to the mess if you start overriding cascading rules everywhere.
Use it wisely, and only if you absolutely must.
Want to learn more?
The rest of this tutorial is available for free on Skillshare as a part of the much larger and far more detailed video course. If you’re new to Skillshare, you’ll also get premium access to more than 22.000 courses. Remember, that you won’t be charged anything for your first 14 days and you can cancel your membership whenever you want within that period. Skillshare is Netflix for life-long learners.