Skip to main content
Syllabus
On this page

CSS Basic Selectors: Type, Class, ID, Universal & Grouping

Badar KhalilUpdated September 29, 2026 4 min read

CSS Basic Selectors: How to Target HTML Elements

CSS selectors are patterns that tell the browser which HTML elements a rule should style. Without selectors, CSS cannot work: they are the bridge between your HTML and your design. This lesson covers the five basic CSS selectors every developer uses daily: type, class, ID, universal and grouping.

Selector Anatomy Recap

In the rule p { color: blue; }, the part before the curly braces (p) is the selector. The browser scans the DOM, finds every element that matches, and applies the declarations inside the braces.

1. Type Selector (Element Selector)

A type selector matches every element of a given HTML tag name, for example p, h1, a, li, button.

  • Syntax: the tag name with no prefix.
  • Use it for: global defaults such as body text, headings and links.
  • Specificity: very low (0,0,1), so it is easy to override.
  • Caution: it affects every matching element on the page, so keep type selectors for broad base styles.

2. Class Selector

A class selector matches elements whose class attribute contains the given name. It starts with a dot.

  • Syntax: .card matches class='card'.
  • Reusable: the same class can be used on many elements.
  • Combinable: an element can have several classes (class='btn btn-primary large').
  • Compound classes: .btn.primary (no space) matches elements that have both classes.
  • Specificity: (0,1,0).
  • Best practice: classes are the main tool of modern CSS. Prefer them over IDs for styling.

3. ID Selector

An ID selector matches the single element whose id attribute has the given value. It starts with a hash symbol.

  • Syntax: #header matches id='header'.
  • Unique: an ID must appear only once per page.
  • Specificity: high (1,0,0), which makes it hard to override later.
  • Best practice: use IDs for anchor links, JavaScript hooks and form labels, but avoid them for styling.

4. Universal Selector

The asterisk matches every element on the page.

  • Specificity: zero (0,0,0).
  • Most common use: a box-sizing reset (*, *::before, *::after { box-sizing: border-box; }).
  • Scoped use: .sidebar * targets everything inside a sidebar.
  • Caution: avoid heavy declarations on the universal selector in large pages.

5. Grouping Selector (Selector List)

Separate selectors with commas to apply one set of declarations to several selectors. This keeps your CSS DRY (Don't Repeat Yourself).

  • h1, h2, h3 { font-family: Georgia, serif; }
  • Each selector in the list is evaluated independently.
  • In modern CSS, a selector list is valid inside :is(), :where() and :not(), and in nested rules.
  • Older browsers may drop an entire list if one selector is invalid, but modern forgiving selector lists (inside :is() and :where()) skip only the invalid one.

Comparison Table

SelectorExampleMatchesSpecificity
Universal*Every element0,0,0
TypepAll p elements0,0,1
Class.alertElements with class alert0,1,0
ID#logoThe element with id logo1,0,0
Compoundp.alertp elements with class alert0,1,1
Groupingh1, h2Any selector in the listEach scored separately

Combining Basic Selectors

You can combine a type and a class with no space, like a.button, to be more precise. Be careful with the space: .card p means paragraphs inside a card, while .card.p means an element with both classes.

Class vs ID: Which Should You Use?

  • Use classes for styling, because they are reusable and keep specificity low and predictable.
  • Use IDs for unique hooks: in-page navigation (href='#contact'), form label associations and JavaScript.
  • Class names are case-sensitive in standards mode: .Card and .card are different.

Naming Tips

  • Use lowercase kebab-case: .main-nav, .hero-title.
  • Name by purpose, not appearance: .alert-error rather than .red-text.
  • Consider a naming methodology such as BEM: .card__title--large.
  • Class and ID names cannot start with a digit and cannot contain spaces.

Modern CSS teams keep selectors flat (mostly single classes) so styles are easy to override and refactor. This is also why utility-first approaches such as Tailwind CSS, cascade layers (@layer) and :where() are popular. Understanding the basic selectors well is what makes these tools easy to learn.

Common Mistakes

  • Forgetting the dot or hash (writing card instead of .card).
  • Reusing the same ID on several elements, which is invalid HTML.
  • Adding a space in a compound selector and accidentally changing its meaning.
  • Overusing the universal selector for expensive declarations.
  • Depending on IDs for styling, then needing !important to override them.

Key Takeaways

  • Type selectors target tags, classes target reusable groups, IDs target one unique element.
  • The universal selector matches everything and has zero specificity.
  • Grouping with commas avoids repeated declarations.
  • Prefer classes for styling to keep specificity low and CSS maintainable.
Try it Yourself HTML
Output

Press Run to execute.

Try it Yourself HTML
Output

Press Run to execute.

Try it Yourself HTML
Output

Press Run to execute.

Try it Yourself HTML
Output

Press Run to execute.

Try it Yourself HTML
Output

Press Run to execute.

Exercise: Pick the Right SelectorHTML

Write CSS so that: (1) all paragraphs are dark gray (#444), (2) elements with the class 'notice' have a light yellow background, (3) the element with id 'logo' is 32px in size and bold. Then group h2 and h3 into a single rule with the color teal.

Try it Yourself HTML
Output

Press Run to execute.

Show expected output
Gray paragraphs, yellow notice background, bold 32px logo, teal h2 and h3.

This is a self-check — compare your result with the expected output above.

Exercise: Compound vs DescendantHTML

Make only the paragraph that has BOTH classes 'msg' and 'error' red, and make paragraphs inside the div with class 'panel' italic. Do not affect any other paragraph.

Try it Yourself HTML
Output

Press Run to execute.

Show expected output
.msg.error { color: red; } .panel p { font-style: italic; }

This is a self-check — compare your result with the expected output above.

Was this page helpful?