edubun 한국어

Selectors and the cascade

When two rules give the same element different colours, CSS does not guess. It compares the selectors, and an id beats any number of classes.

Choosing elements

A selector is a pattern that matches elements in the page. The simplest ones match by element name, by class or by id. p is a type selector and matches every paragraph. .note is a class selector and matches every element with class="note"; one element can have several classes separated by spaces, and one class can be used on many elements. #intro is an id selector and matches the single element with id="intro". *, the universal selector, matches everything.

p { line-height: 1.5; }            /* every p */
.note { background: #fff4d6; }     /* class="note" */
#intro { font-size: 20px; }        /* id="intro" */
h1, h2 { font-weight: 600; }       /* group: h1 and h2 */
nav a { text-decoration: none; }   /* a anywhere inside nav */
ul > li { margin: 4px 0; }         /* li that is a direct child of ul */
a:hover { text-decoration: underline; }
input[type="email"] { width: 20em; }
Simple, grouped, combined, pseudo-class and attribute selectors.

Combining selectors

A comma groups selectors that share the same declarations, so h1, h2 styles both. A space is the descendant combinator: nav a matches links anywhere inside a nav, however deep. > is stricter and matches only direct children. Writing two simple selectors together with no space, as in a.active, means one element must match both: a link that also has the class active. Attribute selectors in square brackets match by attribute, such as input[type="email"].

Pseudo-classes, written with one colon, select elements in a particular state or position: :hover while the pointer is over it, :focus-visible when it has keyboard focus, :first-child when it is the first child of its parent. Pseudo-elements, written with two colons, style a part of an element, such as ::first-line or ::placeholder.

When rules disagree

Often several rules set the same property on the same element. The cascade, the C in CSS, decides which one wins. Leaving aside the browser's own styles and !important, two questions settle almost every case. First, which selector is more specific? Specificity is counted as three numbers: ids, then classes (including attribute selectors and pseudo-classes), then element names. #menu a scores 1-0-1, .active scores 0-1-0, and nav a scores 0-0-2. The numbers are compared from the left, so one id beats any number of classes. Second, if specificity is equal, the rule that comes later in the stylesheet wins.

Inline style attributes beat any selector, and a declaration marked !important beats normal ones. Both are tempting quick fixes, but they make the next change harder, because the only way to override them is with more of the same. Most teams keep specificity low and even, styling mostly with classes, so that order in the file is enough to predict the result.

Inheritance

Some properties pass from parent to child automatically. Set color or font-family on body and every paragraph, list and table cell inside picks it up, unless a rule sets its own. Text-related properties generally inherit; box-related ones such as width, padding, border and margin do not, which is why a border on a section does not appear around every paragraph inside it. The keyword inherit forces a property to copy its parent's value.

Name classes by what something is, not by how it looks. .warning still makes sense when the designer changes the colour from red to orange; .red-text does not. Ids are unique, so they are best kept for link targets and form labels rather than for styling, which keeps specificity low.

type selectorp, h1, a: every element of that name
class selector.name: every element with that class
id selector#name: the one element with that id
descendant combinatorA space: nav a = a anywhere inside nav
pseudo-class:hover, :focus-visible: a state or position
specificityids-classes-types, compared from the left
cascadeThe rules that decide which declaration wins
inheritanceText properties pass from parent to child
  1. Which selector matches <p class="note">?
    • .note
    • #note
    • note
  2. What does nav a match?
    • Links anywhere inside a nav
    • nav elements and all links
    • Only links that are direct children of nav
  3. What does h1, h2 do?
    • Applies the rule to both h1 and h2
    • Matches h2 inside h1
    • Matches nothing
  4. What is the specificity of #menu .item a?
    • 1-1-1
    • 0-2-1
    • 1-0-2
  5. .a.b.c (0-3-0) and #x (1-0-0) set different colours on one element. Which wins?
    • #x
    • .a.b.c
    • The one written later
  6. Two rules have equal specificity. Which wins?
    • The one later in the stylesheet
    • The one earlier
    • Neither applies
  7. Which property is inherited by default?
    • color
    • border
    • padding
  8. Which pseudo-class styles an element that has keyboard focus?
    • :focus-visible
    • :hover
    • :first-child
  9. What does a.active match?
    • A link that has the class active
    • Any element with class active inside a link
    • All links and all .active elements
  10. Why avoid !important for everyday fixes?
    • It can only be overridden by more !important, so later changes get harder
    • It is not valid CSS
    • It slows the browser
Key points
  • p, .class, #id; comma groups; space means descendant; > means child.
  • Specificity ids-classes-types decides; ties go to the later rule.
  • Text properties inherit; box properties do not.