CodeFlow Academy Logo CodeFlow Academy Get Started
Get Started

CSS Selectors and Specificity Explained

Understanding selectors is crucial. We’ll cover classes, IDs, pseudo-classes, and why specificity matters when your styles aren’t applying the way you expect.

10 min read Beginner February 2026
Colorful CSS code displayed on laptop screen with developer tools panel showing styling properties and values

Why Selectors Matter

If you’ve ever written a CSS rule and wondered why it didn’t work, you’ve met the specificity problem. It’s one of those things that seems simple at first — just target an element and style it, right? But CSS selectors are more nuanced than that.

The browser has to decide which styles actually apply when you’ve got multiple rules targeting the same element. That’s where specificity comes in. It’s not magic, and it’s not broken — it’s just a system with rules. Once you understand how it works, you’ll stop fighting against CSS and start writing styles that actually stick.

We’re going to walk through the most common selectors you’ll use, show you how specificity gets calculated, and give you practical strategies for keeping your stylesheets organized and predictable.

Developer workspace with multiple monitors showing CSS code, color swatches, and design system documentation spread across screens

Types of Selectors

CSS gives you several ways to target elements. Each type has its own specificity weight, and understanding these weights is the key to controlling which styles win.

Element Selectors

Target all instances of an HTML tag. Super simple, very low specificity. p { color: blue; } hits every paragraph on the page.

Class Selectors

Target elements with a specific class. Much more specific than element selectors. You can reuse classes across multiple elements — that’s the whole point. .button { padding: 1rem; }

ID Selectors

Target a single element with a unique ID. These have very high specificity, which can create problems if you’re not careful. #header { background: white; } — and there should only be one element with that ID.

Attribute Selectors

Target elements based on their attributes. input[type="email"] targets only email inputs. Same specificity as a class selector.

Pseudo-classes

Target elements in a specific state or position. a:hover , li:first-child , input:focus — same specificity as a class.

Visual breakdown of CSS specificity calculation showing scoring system with inline styles, IDs, classes, and elements represented as stacked blocks

How Specificity Actually Works

Specificity is calculated as a four-part score. Don’t let that intimidate you — it’s straightforward once you see it.

The four parts are: inline styles, IDs, classes and pseudo-classes, and elements . When you write a selector, you count how many of each type you’re using. A selector with more IDs will always beat one with just classes. A selector with classes will beat one with just elements.

Here’s the thing though — you’ll rarely need to think about specificity in numbers. Just remember this: avoid using IDs for styling (they’re too specific), stick with classes, and you’ll stay out of trouble. If a style isn’t applying, the problem is almost always that a more specific selector is overriding it.

“The best CSS is the CSS you don’t have to override. Write specific enough to target what you need, but not so specific that you paint yourself into a corner.”

Combinators and Complex Selectors

Once you’re comfortable with basic selectors, you can combine them to target elements more precisely. Combinators let you say things like “paragraphs inside a div with the class article” or “links that come right after a heading.”

The descendant combinator (space) is the most common: .article p targets all paragraphs inside anything with class article. The child combinator ( > ) is more specific — it only targets direct children. .article > p means paragraphs that are immediate children of an element with class article, not nested deeper.

There’s also the adjacent sibling combinator ( + ) which targets the next element in the flow, and the general sibling combinator ( ~ ) for any sibling that follows. These are powerful for styling things like the first paragraph after a heading differently than the rest.

Best Practices for Maintainable CSS

01

Keep Specificity Low

Use classes instead of IDs. Avoid nesting selectors too deeply. The simpler your selector, the easier it is to override when you need to. A single class is almost always better than a long chain of selectors.

02

Use Meaningful Class Names

Name your classes for what they do, not what they look like. Don’t use .red-text — use .warning-message . When the design changes, your HTML stays accurate and your CSS is still clear.

03

Avoid !important

Just don’t. If you’re reaching for !important, it’s usually a sign that your specificity is out of control. Fix the root cause instead. You’ll thank yourself later when you’re trying to debug why a style won’t change.

04

Be Consistent with Naming

Pick a naming convention and stick with it. BEM (Block Element Modifier) works great for keeping your classes organized and predictable. Whatever you choose, consistency makes your stylesheets way easier to maintain over time.

05

Test Your Selectors

Open DevTools, inspect elements, and verify that your selectors are targeting what you expect. You can see the specificity calculation there too. It’s the fastest way to debug style issues.

06

Use CSS Variables

Define reusable values in your CSS variables. It’s not about selectors per se, but it keeps your stylesheets maintainable and makes global changes a breeze. Colors, spacing, fonts — put them in variables.

Moving Forward

CSS selectors and specificity aren’t complicated once you understand the core concepts. You don’t need to memorize specificity scores — just remember that IDs are high-specificity, classes are medium, and elements are low. Prefer classes, avoid IDs for styling, and keep your selectors simple.

The real skill is writing selectors that are specific enough to target what you need but flexible enough that you can maintain your code months or years later. That comes from practice and from learning to use DevTools to see what’s actually happening in your browser.

Once you’ve got selectors down, you’re ready to tackle more advanced CSS — layouts, animations, responsive design. Everything builds on this foundation.

Disclaimer

This article provides educational information about CSS selectors and specificity. Browser behavior, CSS specifications, and best practices can evolve over time. While we’ve aimed for accuracy, web technologies update frequently. For the most current CSS specifications and browser compatibility information, refer to W3C CSS specifications or MDN Web Docs . Your specific project requirements, browser support needs, and design system may require different approaches than those discussed here.