Loading Page Content...
Preparing courses, live labs, and learning resources.सामग्री लोड हो रही है, कृपया प्रतीक्षा करें...
Preparing courses, live labs, and learning resources.सामग्री लोड हो रही है, कृपया प्रतीक्षा करें...
Have you ever written a CSS rule that was 100% correct, refreshed your browser, and were baffled to see that your style didn't apply at all? 🥊
Every web developer has been there:
When two or more competing CSS rules target the exact same element and set the same property, the browser doesn't flip a coin or pick randomly.
It runs a mathematical calculation called CSS Specificity!
In this lesson, you will master:
(Inline, ID, Class, Element)To understand how specificity works, look at an Olympic Medal Table:
+-------------------------------------------------------------------------+ | THE 4-COLUMN SPECIFICITY MATRIX | +-------------------------------------------------------------------------+ | [ A ] INLINE STYLES --> 🥇 GOLD MEDALS | | Written directly on the tag: <p style="color: red;"> | | | | [ B ] ID SELECTORS (#id) --> 🥈 SILVER MEDALS | | High-priority identifier: #student-profile | | | | [ C ] CLASSES, ATTRS, PSEUDOS --> 🥉 BRONZE MEDALS | | .card, [type="text"], :hover, :first-child | | | | [ D ] ELEMENTS & PSEUDO-ELEMENTS --> ⭐ PARTICIPATION BADGES | | div, p, h1, span, ::before, ::after | +-------------------------------------------------------------------------+
In the Olympics, Country A with 1 Gold Medal beats Country B with 50 Silver Medals, and Country B with 1 Silver Medal beats Country C with 10,000 Bronze Medals!
Specificity works the exact same way: Column values are compared from left to right. A higher value in an earlier column wins immediately!
(A, B, C, D)Every selector on the web can be broken down into a 4-number score:
| Column | What Counts Here? | Score Value |
|---|---|---|
| A | Inline style="..." attribute | (1, 0, 0, 0) |
| B | ID selectors (#navbar, #hero) | (0, 1, 0, 0) |
| C | Classes (.btn), Attribute selectors ([required]), Pseudo-classes (:hover) | (0, 0, 1, 0) |
| D | Element tags (p, div, h1), Pseudo-elements (::before) | (0, 0, 0, 1) |
* $\to$ (0, 0, 0, 0)>, +, ~, space $\to$ (0, 0, 0, 0):not()) adds 0, but the selector inside its parentheses does count!Look at these 5 competing selectors:
pp).(0, 0, 0, 1)div.container p.container), 2 Elements (div, p).(0, 0, 1, 2)nav ul.menu li a:hover.menu) + 1 Pseudo-class (:hover), 4 Elements (nav, ul, li, a).(0, 0, 2, 4)#header .nav-link#header), 1 Class (.nav-link), 0 Elements.(0, 1, 1, 0)<p style="color: red;">(1, 0, 0, 0)Now, compare Selector 3 vs Selector 4:
(0, 0, 2, 4)(0, 1, 1, 0)Who wins?
Even though Selector 3 had 2 classes and 4 elements, its Column B is 0. Selector 4's single ID completely trumps it!
When the browser renders a webpage, it follows this strict priority ladder:
+-------------------------------------------------------------+
| STEP 1: Importance |
| Does any rule have !important? |
| If yes, that rule wins immediately! |
+-------------------------------------------------------------+
| (No !important)
v
+-------------------------------------------------------------+
| STEP 2: Specificity Score |
| Calculate (A, B, C, D) for all matching rules. |
| The highest specificity score wins! |
+-------------------------------------------------------------+
| (Exact Specificity Tie)
v
+-------------------------------------------------------------+
| STEP 3: Source Order (Last Rule Wins!) |
| Whichever rule is written lowest down in your CSS |
| stylesheet (or imported later) wins the tie! |
+-------------------------------------------------------------+To prevent painful "specificity wars" in large projects:
.card, .btn-primary) rather than long tag chains (body div.wrapper section.content div.card).(0, 1, 0, 0). Once you style with an ID, you cannot override it with a class without writing another ID! Reserve IDs for JavaScript anchors.style="..." has specificity (1, 0, 0, 0) which is almost impossible to override from an external stylesheet.| Bad Practice ❌ | Why It Fails ⚠️ | Better Approach ✅ |
|---|---|---|
| Thinking specificity is a base-10 number (e.g. 10 classes = 1 ID) | 100 classes will never roll over to beat 1 ID! Columns are strictly independent. | Recognize that column 2 beats column 3 regardless of quantity. |
Using #id selectors everywhere in CSS | Makes components non-reusable and creates massive specificity hurdles. | Use .class names for all reusable styling. |
| Re-declaring a rule at the bottom of the file expecting it to win, when an earlier rule had higher specificity | Source order only breaks ties when specificity scores are 100% equal! | Calculate the score; raise the class specificity if needed. |
| Forgetting that pseudo-classes have the same weight as classes | :hover, :focus, and [type="text"] all contribute to Column C. | Factor pseudo-classes into your specificity math. |
(Inline, ID, Class, Element).(1,0,0,0) > ID (0,1,0,0) > Class/Pseudo (0,0,1,0) > Element (0,0,0,1).!important) $\to$ Specificity Score $\to$ Source Order (Last rule declared wins).div#profile-card p.bio?.c1.c2.c3...) combined together override a single ID selector #header?*) contribute?specificity-tournament.html.How data and code flow step-by-step
style="color: purple;" to see it beat the ID! 🎯Continue learning with hands-on practice, examples, and exercises in the upcoming topic.
Test your understanding of this lesson with 5 questions. Each question has one correct answer.