Table of Contents
Lets start with the following question:
What will be the result of the following DOM?
<style>
main p {
color: red;
}
main p {
color: green;
}
</style>
<main>
<p>Text 1</p>
</main>
<p>Text 2</p>
Here we have 2 same selectors but different properties.
But as you can see from the screenshot only the second one is being applied, not the first one.
Reason behind that is the fact, that always the last defined properties will be applied which are present for one specific selector. No matter if the CSS is applied via an extra .css file or via inline CSS in the DOM.
Elements, Classes, IDs and inline styling
Element selectors
Element selectors do no have a prefix and therefore contain only of the HTML tags without the <>
main {
color: red;
}
<main></main>
Class selectors
Class selectors have a prefix of .
and are applied on all HTML elements with the given class attribute.
.my-class {
color: green;
}
<div class="my-class"></div>
<main class="my-class"></div>
<p class="my-class"></p>
ID selectors
ID selectors have a prefix of #
and are applied to all HTML elements with the defined ID attribute.
But I have to mention that – due to the HTML specification – there should only be one elements with a specific unique ID!
#my-id {
color: teal;
}
<div id="my-id"></div>
The priority
Now the important part: When does one selector rule over another?
As we already mention only the last defined properties of a selector are applied. But what if we have no other way to just include our CSS in the middle of 2 other selectors?
Problem
<style>
p {
color: red;
}
<!-- PLUGIN CSS START -->
p {
color: green;
}
<!-- PLUGIN CSS END -->
</style>
<main>
<p>Text 1</p>
</main>
As you can see in the HTML comments this example tries to show what can happen if CSS is added to your webpage at the very end of the <head> area. But we want to have red text, not green.
Solution
Increase the “specificity” of our selector.
<style>
main p {
color: red;
}
<!-- PLUGIN CSS START -->
p {
color: green;
}
<!-- PLUGIN CSS END -->
</style>
<main>
<p>Text 1</p>
</main>
How does this work?
The browser gives each selector a “ranking” so it can decide which selectors should be applied.
This ranking is built up with this system:
Here are some examples:
Selektor | Specificity |
---|---|
p | 0001 |
main p | 0002 |
.active a | 0011 |
#menu .active | 0110 |
ul#menu li.active a | 0113 |
body.ie11 .col-3 h2 | 0022 |
The evil !important
You “can” add a !important
to each property inside a selector to “force” your property.
.my-class {
color: red !important;
}
#my-id {
color: green;
}
<div class="my-class" id="my-id"></div>
The !important
increases “specificity” of your property by 10000 (like adding another column at the very beginning of the image) and therefore the <div>
will be shown in red instead of green.
The main problem here is the fact, that its pretty hard to extend after that adjustment.
Best Practises for specificity
Basically you should keep your “specificity” as low as possible.
Therefore you should mainly use element and class selectors and avout ID selectors, inline style sttribute and !important.
A very popular approach is e.g. the BEM model to create an extensible class based structure.
Source: https://css-tricks.com/specifics-on-css-specificity/