CSS Selector Basics: Type, Class, ID, and When to Use Each

Published Updated

The three selectors you will use constantly are the type selector, the class selector, and the id selector, and each one targets elements a different way. For the broader styling basics, start with the guide to CSS. This guide is part of our CSS Selectors series.

Syntax

p {
  /* type: every <p> element */
}

.card {
  /* class: every element with class="card" */
}

#header {
  /* id: the one element with id="header" */
}

Type Selectors

A type selector matches every element of a given tag name, so p styles all your paragraphs at once. These are great for setting sensible defaults across a whole document, like a base line-height or a heading color:

h2 {
  margin-block: 1.5rem 0.5rem;
}

a {
  color: var(--color-link);
}

Because a type selector hits every matching tag, it reaches wide by design. Use it for the baseline look of an element, then narrow things down with a class wherever a specific instance needs to differ.

A type selector has lower specificity than a class or ID selector. When importance and cascade layer are equal, the more specific selector wins. That makes type selectors useful for defaults that a class can override later.

Class Selectors

A class selector starts with a dot and matches any element carrying that class in its class attribute. This is the selector you will reach for most, since one class can apply to many elements and one element can carry several classes:

.button {
  padding: 0.5rem 1rem;
  border-radius: 0.375rem;
}

.button.is-primary {
  background: var(--color-accent);
}

That second rule only matches elements with both button and is-primary on them. Classes give you reusable, predictable styling hooks, which is why component-driven CSS leans on them so heavily.

You can also stack classes on one element the way .button.is-primary does above, layering a specific variant on top of a general pattern instead of writing a whole new rule. That is the idea behind naming systems like BEM, where a block class supplies the shared look and a modifier class swaps out one piece of it. Reusing classes this way keeps a stylesheet shorter and keeps your intent readable when you come back to it months later.

ID Selectors

An id selector starts with a hash and targets the single element whose id matches. An id is supposed to be unique on the page, so reach for one when you mean one specific element:

#main-nav {
  position: sticky;
  top: 0;
}

An id is not only a styling hook. It anchors in-page links, so a URL ending in #main-nav jumps the browser straight to that element, and it gives JavaScript a fast way to grab one specific node with document.getElementById. That dual duty is exactly why you want styling-by-id to stay light. The moment a script or an anchor link depends on that id, a styling change means touching code elsewhere too.

Should You Use a Type, Class, or ID Selector?

Reach for a type selector when a style should apply everywhere that tag shows up. Reach for a class when you need a repeatable pattern that some elements opt into and others skip. Save an id for the rare element that is one of a kind, like a page header or a single modal root. Most real stylesheets lean hard on classes for exactly this reason, using type selectors sparingly for real document-wide defaults and ids sparingly for landmarks. Writing an id selector just to win a specificity fight is usually a sign to add a class instead.

Why Are ID Selectors Hard to Override?

An ID selector has higher specificity than a class selector. When importance and cascade layer are equal, the ID rule wins, which can make it awkward to override later. You set a #main-nav color, then a .dark-theme class fails to change it, and the page looks broken for no obvious reason. Lean on classes for styling and save ids for anchors and JavaScript hooks, and your overrides will keep working. The specificity guide walks through exactly how that scoring adds up.

Example

/* type: all paragraphs get comfortable spacing */
p {
  margin-block: 0 1rem;
}

/* class: reusable highlight you can drop anywhere */
.highlight {
  background: #fff3cd;
}

/* id: one specific landmark element */
#page-footer {
  border-top: 1px solid var(--color-border);
}
<p class="highlight">This paragraph gets both the type rule and the class rule.</p>
<footer id="page-footer">This footer gets the id rule.</footer>

The paragraph picks up its spacing from the type rule and its yellow background from the class, since both selectors match it. The footer takes its top border from the id rule. Each element ends up wearing every rule whose selector it matched.

Frequently Asked Questions

Can an element have more than one class?

An HTML element can have multiple space-separated class names. CSS rules for each matching class can apply to the element, with the cascade resolving conflicting declarations.

Is it valid to reuse the same id on more than one element?

An HTML id must be unique within its document. CSS may still style duplicate IDs, but duplicate values make fragment links and JavaScript lookups unreliable. Use a class when several elements need the same styling.

Can a class name start with a number?

An HTML class name can start with a number, but a CSS class selector must escape that leading digit. Starting class names with a letter avoids that extra syntax. A hyphen followed by a digit also needs escaping in a CSS identifier.

What does the CSS universal selector do?

The CSS universal selector, *, matches every element within its scope and adds zero specificity. It is useful for shared defaults such as box-sizing. Other cascade rules still decide whether its declarations win.

Do inline styles count as a selector?

Inline styles have no selector. Normal declarations in an HTML style attribute take precedence over normal author stylesheet declarations. An important author declaration can override a normal inline declaration, but an important inline declaration has stronger precedence.

Sources

  1. [1]
    Type selectors
    (developer.mozilla.org)
  2. [2]
    Class selectors
    (developer.mozilla.org)
  3. [3]
    ID selectors
    (developer.mozilla.org)
  4. [4]
    Specificity
    (developer.mozilla.org)