Problem
.page .wrapper .content .card .title {
margin: 0;
}Deep selectors couple styles to markup structure and make safe overrides harder.
Learn
Most CSS problems are architectural problems rather than syntax problems. They often start as small shortcuts that compound over time. Use the checklist and examples below to recognise those patterns early.
!important abuseTeams often create accidental complexity when architecture is missing, inconsistent, or disconnected from platform features.
Most anti-patterns are symptoms, not root causes. Before fixing the selector, ask what architectural decision created it.
Fixing symptoms without fixing ownership creates cleaner-looking bad CSS. The underlying issue remains.
.page .wrapper .content .card .title {
margin: 0;
}Deep selectors couple styles to markup structure and make safe overrides harder.
.product-card > .title {
margin: 0;
}Use shallow scoped component selectors with clear ownership.
#app .product-list .product-card .title {
color: red !important;
}IDs and important declarations create override battles and ongoing debugging cost.
@layer components, theme;
@layer theme {
.product-card > .title {
color: red;
}
}Check layer order before increasing specificity.
<article class="p-l m-b-xl bg-dark text-light radius-m grid gap-m">
...
</article>Too many utilities hide component intent and turn HTML into a styling spreadsheet.
<article class="product-card product-card--featured">
...
</article>Use semantic components and keep utilities rare.
.card {
padding: 17px;
border-radius: 13px;
color: #4a2cff;
}Magic numbers and random colours destroy consistency and weaken design systems.
.card {
padding: var(--space-m);
border-radius: var(--br-m);
color: var(--c-accent);
}Use tokens so spacing, colour, and radius stay predictable.
.button--loading {}
.button--disabled {}
.button--active {}Temporary UI behaviour gets mixed with reusable component variants.
.button {}
.button.is_loading {}
.button.is_disabled {}Use modifiers for variants and .is_* classes for temporary state.
Prefer to avoid z-index whenever you can. Most stacking issues are really ownership and paint-order problems in disguise.
When you do need it, keep values as low as possible. A small, boring scheme is often enough: for example main content at 1, footer at1, and header at 2 so sticky headers (or other awkward layout choices) stay predictable without starting a numeric arms race.
.modal {
z-index: 999999;
}If your z-index needs six digits, the problem is probably not ambition.
.modal {
z-index: var(--layer-modal);
}Use named layer tokens and predictable stacking rules instead of arbitrary large numbers.
For modals and similar overlays, prefer native patterns when they fit the content and context: <dialog>, the Popover API, or another appropriate built-in. The platform handles focus and the top layer, and you often do not need to think about z-index at all.
Use practical rules to prevent these problems before they happen.
Most specificity issues begin when override order is accidental.
Legacy systems create most anti-patterns. Learn how to reduce them safely.
Review whether known anti-patterns are present in your codebase.