Selectors
A selector is how you call out to someone in a crowd. The trick is calling out to exactly the right people.
Imagine you're standing on a stage in front of a big crowd, holding a microphone. You need to give instructions. How do you get the right people to listen?
- "Everyone, please stand up."
- "All teachers, raise your hand."
- "Everyone wearing a red team jersey, move to the left."
- "Maria Santos, please come to the front."
- "Anyone carrying an umbrella, leave it at the door."
Each of those is a different way of choosing who the instruction is for. CSS selectors work exactly the same way. And here's the good news: you already did the hard part in the HTML track, when you gave your elements tags, classes, and ids. Now those labels pay off.
Type selectors: "all teachers"
p {
line-height: 1.6;
}A plain element name selects every element of that type. Every <p>, everywhere on the page. It's broad, which is great for setting base styles, like "all paragraphs are comfortable to read."
Class selectors: "everyone in a red jersey"
.price {
color: #2f6f8f;
font-weight: bold;
}A dot followed by a class name selects every element wearing that class, whatever type of element it is. Remember the team jersey analogy from Attributes? This is the coach calling out to the whole team.
Classes are the workhorse of CSS. You'll use them far more than anything else, because they let you decide which elements belong together, instead of being stuck with "all paragraphs" or "one specific thing."
An element can wear several classes, and you can target an element that wears both by chaining them with no space:
.button.danger {
background: crimson;
}That reads "elements that have the button class and the danger class."
ID selectors: "Maria Santos, please come to the front"
#special-offer {
border: 2px dashed orange;
}A hash selects the one element with that id. It works, but here's some honest advice you'll thank me for later: prefer classes for styling. An id can only be used once per page, so a style tied to it can never be reused. And as you'll learn in The Cascade and Specificity, id selectors are so "loud" that they're painful to override. Save ids for links (#contact), form labels, and JavaScript.
The universal selector: "everyone"
* {
margin: 0;
}The asterisk matches every single element. It's powerful and blunt, like shouting at the whole crowd. You'll see it used for a few page-wide resets, like the box-sizing fix in The Box Model.
Attribute selectors: "anyone carrying an umbrella"
You can select elements by their attributes, too:
/* Any input whose type is email */
input[type="email"] {
border-color: #2f6f8f;
}
/* Any link that opens in a new tab */
a[target="_blank"] {
font-style: italic;
}
/* Any link whose href starts with https */
a[href^="https"] {
text-decoration-style: dotted;
}
/* Anything with a data-status attribute at all */
[data-status] {
border-left: 4px solid gray;
}[attr]matches elements that have the attribute at all.[attr="value"]matches an exact value.[attr^="value"]matches values that start with something.[attr$="value"]matches values that end with something, likea[href$=".pdf"]for PDF links.
This is also where those data-* attributes from Attributes Deep Dive start earning their keep. [data-status="sold-out"] can gray out every sold-out product without adding a single extra class.
Grouping: "teachers and parents"
Need the same instruction for two groups? Separate selectors with commas:
h1,
h2,
h3 {
font-family: Georgia, serif;
}Combinators: "the kids standing next to their parents"
This is where the family tree from Nesting and the DOM comes back in a big way. Combinators select elements based on their relationships:
/* Descendant (a space): any a inside nav, at any depth */
nav a {
text-decoration: none;
}
/* Child (>): only li elements that are direct children of this ul */
.menu > li {
color: #2f6f8f;
}
/* Next sibling (+): a p that comes right after an h2 */
h2 + p {
font-size: 1.2rem;
}
/* Later siblings (~): every p that follows an h2 in the same parent */
h2 ~ p {
color: #444444;
}In family terms: a space means descendant (children, grandchildren, anyone further down the tree), > means child (direct children only), + means the very next sibling, and ~ means any younger sibling.
Read selectors from right to left to understand them. nav a is "an a... that's somewhere inside a nav." That's actually how the browser reads them, too.
"There are so many!"
Yes. And if this feels like a lot, that's completely normal. Here's the reassuring part: in day-to-day work, you'll use type selectors for base styles and class selectors for almost everything else. The rest are tools you reach for when you need them. Nobody memorizes them all on day one.
Try it
HTML
CSS
Preview
Try it yourself
- Add a rule using an attribute selector that gives every
[data-status="sold-out"]elementopacity: 0.5;. - Add a rule for
a[href$=".pdf"]that makes PDF links bold. - Remove the underline from only the nav links, using
nav aandtext-decoration: none;.
Check your understanding
Up next
Some selectors can react to what the visitor is doing, or target parts of an element that don't even exist in your HTML. That's Pseudo-classes and Pseudo-elements.
