CSS Selectors: How to Target the Elements You Want to Style

Selectors are how CSS picks which elements a rule applies to. Learn element, class, and id selectors, how to combine them, pseudo-classes like :hover, and how the cascade decides which rule wins.

Published July 8, 20267 min readBy ACY Partner Indonesia
CSS selectors — class, id, and pseudo-class selectors
300 × 250Ad Space AvailablePlace your ad here

In the last article, you saw the shape of a CSS rule: a selector, then a block of declarations. The declarations are the easy part — color: blue; does exactly what it says. The selector is where the real skill lives, because it decides which elements get the styles. Target the wrong elements and your page turns into a mess; target the right ones and everything falls neatly into place.

This article is all about selectors. We’ll cover the three you’ll reach for most, how to combine them, the special “pseudo-class” selectors like :hover, and finally how CSS decides which rule wins when several of them apply to the same element.

Element selectors

The simplest selector targets elements by their tag name. You write the tag name, and the rule applies to every element of that type:

p {
  color: #333;
}

h1 {
  font-size: 32px;
}

The first rule styles every <p> on the page; the second styles every <h1>. This is perfect for site-wide defaults — “all paragraphs should be dark grey,” “all headings should be this size.” But it’s a blunt instrument: it sweeps up every element of that type at once, with no way to single one out. For that, you need classes and ids.

Class selectors

A class selector targets elements that have a specific class attribute. You write a dot (.) followed by the class name. Recall from the HTML attributes article that a class is a label you can put on any element, and many elements can share it.

In your HTML:

<p class="intro">This is the introduction.</p>
<p>This is a normal paragraph.</p>

In your CSS:

.intro {
  font-weight: bold;
  font-size: 20px;
}

The .intro selector only targets elements with class="intro" — so the first paragraph gets bold, larger text, while the second is left untouched. This is the everyday workhorse of CSS. You’ll create classes for buttons, cards, headers, alerts — anything you want to style as a group.

Classes are your main styling tool

In real projects, the vast majority of your styling happens through class selectors. They’re flexible (any element can have any class), reusable (give ten buttons the class button and style them all in one rule), and they keep your intent clear. So when you’re deciding how to target something, reach for a class first — element selectors for broad defaults, classes for everything specific.

ID selectors

An id selector targets the single element with a specific id attribute. You write a hash (#) followed by the id name:

<div id="header">...</div>
#header {
  background-color: #00838f;
}

Because an id must be unique on the page (only one element can have it), an id selector always targets exactly one element. That sounds handy, but in practice most developers prefer classes for styling, even for one-off elements. Why? Classes are more flexible, and id selectors have a side effect on the “cascade” (which we’ll get to in a moment) that can make your styles harder to manage.

Prefer classes over ids for styling

You can style with id selectors, but the common advice is to use classes for styling and save ids for other jobs — like linking to a section (href="#contact") or letting JavaScript grab a specific element. For styling, a class can do everything an id can, with fewer headaches. It’s not a hard rule, but get into the habit of styling with classes and you’ll sidestep a whole category of tricky problems down the road.

Combining and grouping selectors

Selectors get more powerful when you combine them.

Group selectors with a comma to apply the same styles to several at once:

h1, h2, h3 {
  font-family: Georgia, serif;
}

That one rule styles all three heading levels. Without the commas, you’d have to repeat the declarations three times.

Combine selectors to be more specific. Putting selectors next to each other with a space means “an element inside another element”:

.card p {
  color: grey;
}

This targets any <p> that sits inside an element with the class card — and leaves paragraphs elsewhere alone. This “descendant” combination is extremely common: it lets you style elements based on where they sit in the page.

You can also stick selectors together with no space to mean “an element that matches both”:

p.intro {
  font-style: italic;
}

This targets only <p> elements that also have the class intro — not other elements with that class, and not other paragraphs.

Pseudo-classes: styling based on state

Some of the most useful selectors target elements based on their state — what the user is doing to them right now. These are called pseudo-classes, and they’re written with a colon (:).

The classic one is :hover, which applies while the user’s mouse is over an element:

a:hover {
  color: red;
}

Now links turn red the moment you hover over them — the kind of small interactive touch that makes a page feel alive. Here are a few common pseudo-classes:

Pseudo-class Applies when…
:hover The mouse is over the element
:focus The element is focused (e.g. a clicked-into input)
:active The element is being clicked
:first-child The element is the first child of its parent
:last-child The element is the last child of its parent

These let you respond to interaction and position without a single line of JavaScript — it’s pure CSS.

The cascade: which rule wins?

Here’s the question that trips up every beginner sooner or later: what happens when two rules try to style the same element in different ways? For example:

p {
  color: black;
}

.intro {
  color: blue;
}

If a paragraph has class="intro", both rules apply — one says black, one says blue. So which one wins? This is exactly what the “Cascading” in CSS refers to, and it comes down to specificity: more specific selectors beat less specific ones.

The rough order, from weakest to strongest:

  1. Element selectors (p, h1) — least specific.
  2. Class selectors (.intro, :hover) — more specific.
  3. ID selectors (#header) — most specific.

So in the example above, .intro (a class) beats p (an element), and the paragraph turns blue. A class is more specific than a plain tag, so it wins.

When two rules tie, the last one wins

If two selectors have the exact same specificity, the one written later in the CSS wins — so order matters once specificity is tied. This is why a style sometimes seems to “not work”: another rule of equal or higher specificity is overriding it. When a style refuses to apply, the cause is almost always the cascade — something more specific, or something later, is winning. Get this one concept and you’ll save yourself hours of confusion.

There’s also !important, a way to force a declaration to win no matter the specificity. Avoid it. It’s a sledgehammer that makes your styles hard to manage, and reaching for it is usually a sign that something in your selectors needs rethinking instead.

Wrapping up

Selectors are the heart of CSS, and now you can target elements precisely:

  • Element selectors (p) style every element of a type — good for broad defaults.
  • Class selectors (.intro) style any element with that class — your main, everyday tool.
  • ID selectors (#header) style one unique element — but prefer classes for styling.
  • Group selectors with commas, combine them with spaces (descendant) or no space (matches both) to be precise.
  • Pseudo-classes like :hover and :focus style elements based on state — interactivity with no JavaScript.
  • The cascade decides which rule wins, based on specificity (id > class > element), with later rules breaking ties.

Master selectors and you can drop your styles exactly where you want them — which is most of the battle in CSS. Next, we’ll get into one of the most fun parts of styling: colors and backgrounds — the many ways to specify color, and how to fill elements with solid color, gradients, and images.

Tags:cssfrontendselectorsbeginner
728 × 90Ad Space AvailablePlace your ad here

Related Articles

See All Articles

You Might Also Like

Frontend best practices overview cover
Frontend / Fundamentals

Frontend Best Practices: An Overview

A friendly map of what good frontend really means — semantic HTML, clean CSS, unobtrusive JavaScript, responsive layouts, performance, and progressive enhancement, with pointers to go deeper.

Sep 20, 20268 min read
A Frontend Developer Roadmap cover with the path HTML to CSS to JavaScript
Frontend / Fundamentals

A Frontend Developer Roadmap: What to Learn, and in What Order

A calm, step-by-step learning path for beginners: HTML, CSS, JavaScript, developer tools, responsive and accessible design, a framework, TypeScript, and deployment, with the reasoning behind each step.

Sep 20, 202611 min read
Title card reading Styling and Interactivity over a dark blue ACY Partner background
Frontend / Fundamentals

How Styling and Interactivity Work

A beginner-friendly look at how CSS turns plain HTML into a designed layout, and how JavaScript adds behavior — the structure, style, behavior mental model for building web pages.

Sep 20, 20269 min read
Three front-end layers combining on one web page
Frontend / Fundamentals

How HTML, CSS, and JavaScript Work Together

A hands-on walkthrough for beginners: build one small button, give it structure with HTML, looks with CSS, and behavior with JavaScript, and watch the three layers cooperate on a real page.

Sep 20, 20268 min read
The Frontend Developer Toolkit cover with editor, browser, and CLI motifs
Frontend / Fundamentals

The Frontend Developer Toolkit

A friendly tour of the everyday tools a frontend developer relies on — code editor, browser and DevTools, terminal, version control, package managers, and a dev server — and what each one is actually for.

Sep 20, 202610 min read
Cover illustration for What Frontend Developers Do
Frontend / Fundamentals

What Frontend Developers Do: A Beginner's Guide to the Role

A clear, beginner-friendly look at what frontend developers actually do every day: turning designs into working interfaces, building reusable UI, and caring about responsiveness, accessibility, and speed.

Sep 20, 202610 min read