Command Palette

Search for a command to run...

Hectal
PHASE 1Beginner ~25 min· topic 1 of 6

Topic 1.1

Type, Class and ID Selectors

In one line

Type selectors match every element of one kind, class selectors match every element carrying a class name, ID selectors match the one element with that id; the universal selector matches everything and commas group several selectors into one rule.

Think of it like this

A school assembly. The head teacher can call out "all students" (a type selector: every p), "everyone in the red team" (a class: every element with class="red", and one student can be in several teams), or "student number 1042" (an ID: exactly one person). "Everybody in the hall" is the universal selector *.

Words you'll meet

New words in this topic, in plain English. Come back here whenever one feels fuzzy.

Selector
The part of a CSS rule that says which elements to style, like p or .card.
Match
An element matches a selector when it fits the description, so the rule's styles apply to it.
Type selector
A tag name used as a selector, like p or button. It matches every element of that kind.
Class
A name you put in an element's class attribute so CSS can find it. Many elements can share a class.
Class selector
A dot and a class name, like .note. It matches every element that has that class.
ID selector
A hash and an id, like #logo. It matches the element with that id, which should be unique.
Universal selector
The star *. It matches every element.
Selector list
Several selectors separated by commas, so one rule styles all of them.
Specificity
A score the browser gives each selector. When two rules disagree, the higher score usually wins. Phase 2 covers it fully.

Step by step

01Style every element of one type

Start with a type selector. Every paragraph on the page turns grey, wherever it is.

style.csswhole filecss
p {
  color: #555;
}

02Mark some elements with a class

Add class="note" to the elements you want to single out, then select them with a dot. The class can be on any element type: paragraphs, spans, divs.

An element can carry several classes. The order in the attribute doesn't matter: class="note warning" and class="warning note" are the same.

index.htmlwhole filehtml
<p class="note">Remember to save.</p>
<p class="note warning">Unsaved changes will be lost.</p>
<span class="note">Tip</span>

03Narrow it down by chaining

Write selectors together with no space to require all of them on the same element. p.note means "a p that also has class note". .note.warning means "has both classes".

A space would mean something completely different (an element inside another one); that's the descendant combinator in Topic 1.2.

style.csswhole filecss
.note {
  background: #fff8db;
}
p.note {
  padding: 8px;
}
.note.warning {
  border-left: 4px solid crimson;
}

04Use an ID for one unique element

#main-title matches the element whose id is main-title. Ids are case-sensitive and must not contain spaces.

Use ID selectors sparingly. Later, when you want to change that title with a class, the ID rule will beat your class rule because of its higher specificity.

style.csswhole filecss
#main-title {
  color: rebeccapurple;
}

05Group selectors and use the universal selector

Commas let one rule cover several selectors. The universal selector * is mostly used for resets that should touch every element.

style.csswhole filecss
h1, h2, h3 {
  font-family: Georgia, serif;
}

* {
  margin: 0;
}
Group selectors and use the universal selectordiagram
Rendering diagram…

Try it yourself

  1. 1

    Predict, then chain

    In the first example, predict what happens if you change p.note to .note (remove the p). Which extra element gets padding? Run it and check: the span.

  2. 2

    Add a class to an element

    In the first example, add warning to the plain paragraph's class list (class="warning"). Does it get the crimson border? No: .note.warning needs both classes. Add note too and run again.

  3. 3

    Count your own selector

    In the second example, add console.log("span.note:", count("span.note"));. Predict the number first (1), then run.

Code & diagrams

Type, class and ID selectors New tab

Each comment says what the rule matches. Remove `p` from `p.note` and the span gets padding too.

Preview

Press Run to see the page.

Console

Nothing logged yet.
Counting what each selector matches New tab

`querySelectorAll` uses exactly the same selector language as CSS, so JavaScript can tell you how many elements a selector matches. `.Note` matches nothing: class names are case-sensitive.

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

p: 3
.note: 3
p.note: 2
.note.warning: 1
#intro: 1
.Note: 0
.box *: 5
Grouping and the universal selector New tab

Try adding a typo to the list: `h1, h2, h3:hovr`. The whole rule is dropped and all three headings lose their colour.

Preview

Press Run to see the page.

Console

Nothing logged yet.

Break it on purpose

Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.

Break #1

Forget the dot

In the first example, change .note { to note {.

terminal
$ the preview shows
── what you'll see ──
No element has the yellow background any more. No error appears anywhere.

Break #2

One typo kills the whole group

In the third example, change h1, h2, h3 { to h1, h2, h3:hovr {.

terminal
$ the preview shows
── what you'll see ──
All three headings lose the Georgia font and the blue colour, not only h3.

Myth vs fact

Myth

An id can be used on several elements if CSS still works.

Fact

CSS will indeed style every element with a duplicated id, but the HTML is invalid: getElementById returns only the first one, label for and #links point to the first one, and assistive tech can get confused. Keep ids unique and use classes for groups.

Myth

.card.featured and .card .featured are the same.

Fact

No space means both classes on one element. A space means a .featured element somewhere inside a .card. One character changes the meaning completely.

Myth

The universal selector is slow and should be avoided.

Fact

Modern browsers handle * resets with no measurable cost. What costs more is huge numbers of complex selectors re-matched on every change, not a single * rule.

Pro corner

Extra depth for experienced readers. New to this? Skip it for now and come back later.

  • ▸

    Browsers match selectors right to left: for .menu a, the browser starts from each a and walks up looking for a .menu ancestor. The rightmost part (the key selector) decides how many elements get checked, so .menu a is cheaper than .menu *.

  • ▸

    Browsers keep hash tables of rules by id, class and tag of their key selector, so the engine only tests rules that could possibly match an element. That's why class-based CSS scales to thousands of rules.

  • ▸

    Class and id matching is case-sensitive in standards mode but case-insensitive in quirks mode (a page without <!DOCTYPE html>). Another reason to always write the doctype.

  • ▸

    Ids that start with a digit (id="1st") are valid HTML but not a valid CSS identifier: #1st is a syntax error. Escape it as #\31 st or, better, choose ids that start with a letter.

Remember this

  1. 1

    A selector is the part of a CSS rule before the {. It describes which elements the rule's declarations apply to. The browser checks every element on the page against it; every element that matches gets the styles. If nothing matches, the rule does nothing and there is no error message.

  2. 2

    A type selector (also called an element selector) is the bare tag name: p, h1, button. It matches every element of that type, anywhere on the page. In HTML documents type selectors are case-insensitive, so P and p match the same elements, but write them in lower case by convention.

  3. 3

    A class selector is a dot followed by a class name: .card matches every element whose class attribute contains the word card. An element can have many classes separated by spaces (class="card featured"), and you can require several at once by chaining them with no space: .card.featured matches only elements that have both. You can also attach a class to a type: p.note matches only <p> elements with class note. Class names are case-sensitive: .Card does not match class="card".

  4. 4

    An ID selector is a hash followed by an id: #main-title matches the element with id="main-title". An id must be unique in the page. IDs are powerful but heavy-handed in CSS: an ID selector has much higher specificity (priority score) than a class, so ID-based rules are hard to override later. Professionals style with classes and keep ids for links (href="#section"), labels and JavaScript.

  5. 5

    The universal selector * matches every element. On its own it is used for global resets, such as *, *::before, *::after { box-sizing: border-box; } (you'll meet box-sizing in Phase 5). It adds nothing to specificity, so * rules are easy to override.

  6. 6

    A selector list (grouping) joins selectors with commas: h1, h2, h3 { font-family: Georgia, serif; } is the same as writing three rules. One catch: in a plain selector list, if one selector is invalid (a typo like h1, h2:hovr), the browser throws away the whole rule, not only the broken part.

Explain it without notes

01

What is the difference between a type selector, a class selector and an ID selector? When would you use each?

02

What does p.note.warning match, and how is it different from p .note .warning?

03

Why do many teams avoid ID selectors in CSS?

04

What happens to a rule like h1, h2, h3:hovr { color: red }, and why?

Practice

01

Write CSS so every <h2> is dark blue, every element with class tag has a light grey background, and only <span> elements with class tag are bold.

02

Make a single rule that gives h1, h2 and any element with class title the font Georgia, serif.

03

A page has <p class="price sale">₹499</p>. Write a rule that makes it red only when it has both classes.

Trade-offs

  • ↔

    Type selectors are short but broad: button { ... } styles every button, including ones in third-party widgets. Classes are more typing but scoped to exactly what you mark.

  • ↔

    IDs target precisely and are fast to match, but their high specificity makes later overrides painful. Classes give nearly the same precision with far less friction.

Done when you can

  • I can write type, class, ID and universal selectors.

  • I can chain selectors (p.note.warning) and explain how it differs from a space.

  • I can group selectors with commas and know an invalid entry drops the whole rule.

  • I know class names are case-sensitive.

  • I can explain why classes are preferred over IDs for styling.