HTML & CSS · 14-day planAll days
Target exactly the elements you want with descendant, child and attribute selectors and pseudo-classes like :hover and :nth-child. Then learn the rules that decide which style wins when rules disagree, specificity, source order and inheritance, and how to debug them in the browser.
By the end of today you can
- Combine selectors to target elements inside others
- Style states and positions with pseudo-classes such as :hover and :nth-child
- Predict which rule wins using specificity and source order
- Explain which properties are inherited
- Inspect styles with the browser's developer tools
Yesterday's selectors (type, class, id) go a long way. Today you'll learn to aim more precisely, and to understand the cascade: the rules that decide what happens when CSS rules disagree. It's the C in CSS.
Combining selectors
| Selector | Means |
|---|---|
nav a | a anywhere inside nav (descendant) |
ul > li | li that's a direct child of ul |
h2 + p | The p immediately after an h2 |
h2 ~ p | Every p after an h2, same parent |
p.lead | A p that also has class lead (no space!) |
Pseudo-classes: states and positions
A pseudo-class (with one colon) selects elements in a certain state or position:
| Pseudo-class | Matches |
|---|---|
:hover | The mouse is over it |
:focus | It has keyboard focus (e.g. an input you clicked) |
:first-child, :last-child | First / last among its siblings |
:nth-child(even) | 2nd, 4th… (also odd, 3, 3n) |
:not(.done) | Doesn't match .done |
:invalid, :checked | Form states |
Attribute selectors
::after (two colons) is a pseudo-element: it adds content after the element. ::before and ::first-letter work similarly.
When rules disagree
- Specificity: more specific selectors win. Roughly: id (
#first) > class / pseudo-class / attribute (.intro,:hover) > type (p). - Source order: when specificity is equal, the later rule wins.
So the first paragraph is green (id), the second blue (class beats type), and the third orange (the later of two type rules).
Keep specificity low and even: style with classes most of the time, and the cascade stays predictable. !important overrides everything, but it makes CSS hard to change later, so treat it as a last resort.
Inheritance
Some properties pass from parent to child:
- Inherited: text properties:
color,font-*,line-height,text-align. - Not inherited: box properties:
border,padding,margin,background,width.
That's why setting font-family and color once on body styles the whole page.
Your best friend: DevTools
In any desktop browser, right-click an element and choose Inspect. The Elements panel shows the HTML, and the Styles panel shows every rule that applies, which ones are crossed out (overridden), and where they come from. You can edit values live to experiment. On a phone, use your computer for this.
Recap
- Combinators:
nav a(inside),ul > li(child),h2 + p(next);p.lead= both. - Pseudo-classes:
:hover,:focus,:nth-child(),:not(); pseudo-elements:::before,::after. - Who wins: higher specificity (id > class > type), then later in the CSS.
- Text properties inherit; box properties don't.
- Debug with Inspect in DevTools.
Tomorrow: the box model, the key to spacing and sizing everything.
Knowledge check
Test what you learned
5 questions · pick an answer to see if you're right
- 1
What does nav a { } select?
- 2
Two rules set a paragraph's colour: .intro { color: blue } and p { color: red }. Which wins?
- 3
Two rules with the same specificity disagree. Which wins?
- 4
You set color on <body>. Why do paragraphs inside get that colour too?
- 5
What does li:nth-child(odd) select?
Finished day 7?
Mark complete and continue to Day 8: The Box ModelWas this lesson helpful?
Need a breather? Take a two-minute break