Explain why a declaration wins
The cascade resolves competing declarations. Specificity is only one stage. A useful debugging sequence is: confirm a selector matches, compare cascade origin/importance and layer, then specificity and source order within the relevant context. Inheritance supplies some values when an element has no winning declaration of its own.
A small conflict
.tech-lesson-content { color: #334155; }
.card { color: #1d4ed8; }
p { color: #166534; }
.card { color: #7c2d12; }
This paragraph has its own color rule.
The card's later class rule wins over its earlier class rule under otherwise equal cascade conditions. The paragraph is green because its own matching p declaration sets color. The parent's more specific class selector does not compete directly with a declaration on the child; inheritance is a fallback, not a stronger selector.
Specificity as categories
IDs contribute to the ID category; classes, attributes and pseudo-classes to another; types and pseudo-elements to another. Compare categories in order, not as a simple decimal sum. The universal selector and combinators contribute no specificity. :where has zero specificity; :is and :not take specificity from their selector arguments rather than behaving like an ordinary extra class.
Important and layers
!important changes a declaration's cascade priority; it does not make the selector “more specific”. Layer ordering and important declarations have rules that differ from ordinary unlayered declarations. Use developer tools to inspect the actual winner rather than adding more IDs until a rule happens to work.
Inheritance is property-dependent
color and font properties commonly inherit. Margin, padding and borders generally do not. The keywords inherit, initial and unset let you request explicit behavior. A child's inherited value comes from the parent's computed value, not by copying the parent's source rule.
Practice
- Remove the p color rule and observe the paragraph inherit the card's color.
- Swap the two .card rules; equal-priority ties follow source order.
- Inspect a crossed-out declaration and name the actual reason it lost.
- Replace an overly specific component selector with a reusable class and verify the intended states still work.