- CSS Tutorial
- CSS Introduction
- CSS Syntax
- CSS Comments
- CSS Selectors
- CSS Fonts
- CSS Colors
- CSS Backgrounds
- CSS Box Model
- CSS Borders
- CSS Margins
- CSS Padding
- CSS Text
- CSS Images
- CSS Links
- CSS Lists
- CSS Tables
- CSS Outline
- CSS Icons
- CSS Display
- CSS max-witdh
- CSS Position
- CSS z-index
- CSS Overflow
- CSS Float
- CSS Align
- CSS Opacity
- CSS Navigation Bar
- CSS Dropdowns
- CSS Forms
- CSS Units
- CSS !important
- CSS Specificity
- CSS Combinators
- CSS inline-block
- CSS Hover
- CSS Cursors
- CSS Selectors
- CSS Type Selector
- CSS Class Selector
- CSS ID Selector
- CSS Attribute Selector
- CSS Pseudo-class Selector
- CSS Pseudo-element Selector
- CSS Universal Selector
- CSS Advanced
- CSS Text Formatting
- CSS Gradients
- CSS Shadow
- CSS Rounded Corners
- CSS Text Effects
- CSS 2D Transform
- CSS 3D Transform
- CSS Border Images
- CSS Inherit
- CSS Transitions
- CSS Animations
- CSS Box Sizing
- CSS Tooltip
- CSS Masking
- CSS Pagination
- CSS Styling Images
- CSS object-fit
- CSS object-position
- CSS Buttons
- CSS Multiple Columns
- CSS Variables
- CSS Flexbox
- CSS Grid
- CSS Media Queries
CSS Specificity
Specificity is the set of rules browsers use to determine which CSS property values are most relevant to an element and, therefore, should be applied. Think of it as a ranking system or a "weight" assigned to different types of CSS selectors. When multiple rules target the same element and try to change the same property (like color or font-size), the browser calculates which selector has the highest specificity score to pick the winner.
To understand how the browser makes these decisions, we look at the four categories of the specificity hierarchy:
- Inline styles: These are added directly to an element’s
styleattribute in the HTML. They have the highest priority because they are most specific to that exact element. - IDs: Selectors using an ID (e.g.,
#header) are unique identifiers. A single ID is more powerful than any number of classes or elements combined. - Classes, attributes, and pseudo-classes: This category includes class selectors (
.nav-item), attribute selectors ([type="text"]), and pseudo-classes like:hoveror:first-child. - Elements and pseudo-elements: This is the lowest level of specificity. It includes standard HTML tags (
h1,div,p) and pseudo-elements like::beforeor::after.
The specificity score is calculated as a series of four numbers (0,0,0,0). You can visualize it like a leaderboard where the left-most column is the most important:
- Thousands Place (1,0,0,0): Inline styles.
- Hundreds Place (0,1,0,0): ID selectors.
- Tens Place (0,0,1,0): Classes, attributes, and pseudo-classes.
- Ones Place (0,0,0,1): Element (tag) names and pseudo-elements.
When comparing two selectors, the browser moves from left to right. The first selector to have a higher number in a column "wins." If all numbers are equal, the Cascade takes over: the rule defined last in your CSS file is the one that gets applied.
Here’s a practical example to illustrate how these scores interact in a real-world scenario:
CSS
/* Score: (0,0,0,1) - Lowest specificity */
body {
color: blue;
}
/* Score: (0,0,1,0) - Beats the 'body' tag */
.myclass {
color: green;
}
/* Score: (0,1,0,0) - Beats the class and the tag */
#myid {
color: red;
}
/* Score: (0,1,1,0) - Beats the ID alone because it has an ID AND a class */
#myid.myclass {
color: orange;
}
HTML
<!-- Inline style Score: (1,0,0,0) -->
<p id="myid" class="myclass" style="color: pink;">
This text will be pink because inline styles win.
</p>
!important is not part of the specificity calculation, but it acts as a "nuclear option" that overrides everything else. Avoid using it unless absolutely necessary (like overriding 3rd-party library styles), as it makes debugging your CSS a nightmare.
There are a few special cases to keep in mind regarding specificity:
- The Universal Selector (
*) and combinators (like+,>, or~) have no specificity value (0,0,0,0). - The
:not()pseudo-class itself does not add specificity, but the selector placed inside the parentheses does. For example,div:not(.active)has the specificity of one element and one class (0,0,1,1). - Inheritance has no specificity. Styles inherited from a parent element (like a font family set on the
body) are always overridden by direct rules applied to the child element.