Back to Blog
4 min readBy Tanish Bhandari

CSS Selectors 101: Targeting Elements with Precision


CSS Selectors 101: Targeting Elements with Precision

I still remember the frustration. I'd written CSS that was supposed to change the color of one specific button, but somehow every button on the page turned blue. I didn't understand why my styles were affecting things I didn't intend to touch.

The problem was selectors. I was using the wrong ones, targeting too broadly, and creating chaos. Once I learned how selectors actually work, CSS stopped feeling like a guessing game.

What Selectors Actually Do

You've written HTML. You have headings, paragraphs, links, buttons scattered across a page. Now you want to style them.

But how do you tell CSS which element to style? That's the selector's job. It's a pattern that matches elements in your HTML. Whatever matches gets the styles.

Think of it like addressing people in a room:

  • "Hey everyone" — targets all elements
  • "Everyone wearing red shirts" — targets elements with a specific class
  • "Specifically you, Rahul" — targets one unique element by ID

CSS selectors work the exact same way.

Element Selector

The simplest selector. Just use the tag name:

p {
  color: gray;
  line-height: 1.6;
}

This targets every single <p> on the page. All paragraphs turn gray. It's broad, which can be useful for setting baseline styles.

But if you want to style just some paragraphs differently, you need something more specific.

Class Selector

Classes let you group elements that should share styles. In HTML, you add a class attribute. In CSS, you target it with a dot:

.highlight {
  background-color: yellow;
  padding: 4px;
}
<p class="highlight">This stands out.</p>
<p>This doesn't.</p>

Only paragraphs with class="highlight" get the yellow background. Everything else stays normal.

Classes are reusable. You can apply the same class to ten different elements across your page. This is how most CSS organization works in practice.

You can also chain multiple classes:

.card.featured {
  border: 2px solid gold;
}

This only targets elements that have both card and featured classes. More specific, less accidental styling.

ID Selector

IDs are for unique elements. Each ID should only appear once per page.

#main-header {
  font-size: 2.5rem;
  margin-bottom: 20px;
}
<h1 id="main-header">Welcome</h1>

Use the hash symbol (#) to target IDs. Since IDs are unique, this is as specific as you can get without inline styles.

I generally avoid IDs for styling because they're so specific that they're hard to override later. Classes are more flexible. But IDs are perfect for JavaScript hooks or anchor links.

Group Selector

Sometimes you want the same styles on multiple different selectors. Instead of repeating yourself, group them with commas:

h1, h2, h3 {
  font-family: 'Georgia', serif;
  color: #333;
}

All three heading levels get the same font and color. One rule, multiple targets.

Descendant Selector

This one unlocks real power. Target elements inside other elements:

nav a {
  color: white;
  text-decoration: none;
}

This only targets links that are inside a <nav> element. Links elsewhere on the page stay unaffected.

You can chain these deeper:

.sidebar ul li a {
  font-size: 14px;
}

This targets links, inside list items, inside unordered lists, inside elements with class sidebar. Very precise.

Understanding Priority

Here's where beginners get stuck. What happens when two rules conflict?

p { color: blue; }
.intro { color: green; }
#welcome { color: red; }

If an element matches all three, which color wins?

CSS has a specificity hierarchy:

ID (#) > Class (.) > Element

So #welcome beats .intro beats p. The more specific selector wins.

This is why I avoid IDs for styling. They're so powerful that they're hard to override without resorting to !important, which creates its own mess.

Quick Reference

SelectorSyntaxWhat It Targets
ElementpAll <p> tags
Class.nameElements with class="name"
ID#nameElement with id="name"
Groupa, bBoth a and b
Descendanta bb inside a

The Practical Takeaway

Start broad, get specific when needed. Use element selectors for baseline resets. Use classes for most of your styling. Save IDs for truly unique things.

When your styles aren't applying, check your selector. Nine times out of ten, you're either targeting the wrong thing or something more specific is overriding you.

Selectors are the foundation. Get comfortable with these five patterns, and CSS becomes a lot more predictable.



Written by Tanish Bhandari