Type selector
p, h1 or button has low specificity. Useful for base styles.
Specificity measures how strongly a selector targets an element. It is powerful, but if you overuse it, your stylesheet starts fighting itself.
.card__title { color: #8cffc1; }
.card.card--featured .card__title { color: #62d5ff; }
#special-card .card__title { color: #ffb55f; }
Cascade & Control
Specificity is one part of the cascade. When two declarations compete and the cascade reaches selector strength, the browser compares selector specificity.
IDs are stronger than classes. Classes, attributes and pseudo-classes are stronger than type selectors. Inline styles are stronger than normal stylesheet selectors.
The goal is not to write the most specific selector. The goal is to write selectors that are strong enough, readable and easy to override on purpose.
p, h1 or button has low specificity. Useful for base styles.
.card is the normal styling workhorse. Reusable and manageable.
#hero is strong and usually too rigid for reusable styling.
style="" beats normal selectors and should be rare in site CSS.
Visual model
The browser does not apply styles emotionally. It follows a priority system. These diagrams make that priority visible before you start changing declarations.
One type selector. Light and easy to override.
One class selector. Ideal for components.
Two classes. Stronger, but still reasonable.
One ID. Very strong for normal styling.
Examples
.card {
padding: 2rem;
}
.card--featured {
border-color: #8cffc1;
}
.card__title {
font-size: 2rem;
}
#page main .cards article.card.featured h2.title {
color: red;
}
body #page .cards .card h2.title.title {
color: blue;
}
Rules that matter
CSS becomes easier when every override has a reason. If a rule wins by accident, the next developer has to debug your intention instead of the code.
Classes are reusable and do not lock you into exact page structure.
IDs are hard to override and usually belong more to anchors or JavaScript hooks.
Long descendant chains break when markup changes.
.button.button.button is a warning sign.
.button--danger is clearer than .modal footer div .button.
A crossed-out declaration may have lost to a stronger selector.
Production thinking
Specificity decides how hard future changes become. Low, intentional specificity makes CSS feel calm; accidental high specificity makes every small change expensive.
High-specificity rules can accidentally override focus states, font sizes and contrast fixes. Keep accessibility selectors easy to win.
A scalable stylesheet should avoid specificity spikes. If one selector is much heavier than the rest, document the reason or simplify it.
Specificity itself is not an SEO factor, but maintainable CSS helps preserve readable, stable pages over time.
Live code lab
The preview runs in an isolated iframe. Links and forms stay inside the practice area, so you can experiment without leaving the lesson.
Mini assignment
Practice assignment
Try it yourself
Self-check
Answer these questions before moving on. If the answer is vague, inspect the lab example and trace which declaration wins.
Senior audit upgrade
A selector can be powerful and still be a bad choice. Good CSS uses enough specificity to be clear, but not so much that every future rule becomes a fight.
Use :where() for low-pressure defaults because it contributes no specificity.
These use the highest specificity inside their selector list, so one ID inside can make the whole selector heavy.
If you need longer and longer selectors, the architecture probably needs cleaning.