Episode 1 — Fundamentals / 1.6 — CSS Core Fundamentals
1.6 — CSS Core Fundamentals: Quick Revision
Compact cheat sheet. Print-friendly.
How to use this material (instructions)
- Skim top-to-bottom in one pass before interviews or exams.
- If a row feels fuzzy — reopen the matching lesson:
README.md→1.6.a…1.6.i. - Drills —
1.6-Exercise-Questions.md. - Polished answers —
1.6-Interview-Questions.md.
1.6.a CSS Syntax & Selectors
Rule anatomy
selector {
property: value; /* declaration */
}
Selector types
| Selector | Example | Specificity |
|---|---|---|
| Element | p { } | 0,0,0,1 |
| Class | .card { } | 0,0,1,0 |
| ID | #hero { } | 0,1,0,0 |
| Universal | * { } | 0,0,0,0 |
| Attribute | [type="email"] { } | 0,0,1,0 |
| Grouping | h1, h2, h3 { } | Each selector scored independently |
Combinators
| Combinator | Name | Meaning |
|---|---|---|
(space) | Descendant | Any depth |
> | Child | Direct children only |
+ | Adjacent sibling | Next sibling |
~ | General sibling | Any following sibling |
Key pseudo-classes
:hover · :focus · :focus-visible · :active · :first-child · :nth-child(n) · :not() · :is() · :has()
:has() — parent selector
.card:has(img) { padding: 0; }
Selects an element based on what it contains — inverts selector direction.
Pseudo-elements
::before · ::after · ::placeholder · ::selection
1.6.b Specificity & Cascade
Cascade priority (highest wins)
- Origin & importance (
!importantflips author/user/UA order) - Inline styles —
style="…"→ specificity1,0,0,0 - Layer order (
@layer) - Specificity — selector weight
- Source order — last wins (tie-breaker)
Specificity scoring
(inline, IDs, classes/attrs/pseudo-classes, elements/pseudo-elements)
| Selector | Score |
|---|---|
p | 0,0,0,1 |
.card | 0,0,1,0 |
#hero | 0,1,0,0 |
nav ul.menu li a:hover | 0,0,2,4 |
IDs beat any number of classes. Classes beat any number of elements.
Special selectors
| Selector | Specificity behavior |
|---|---|
:is() | Takes highest argument's specificity |
:where() | Zero specificity — ideal for defaults |
:not() | Takes argument's specificity |
:has() | Takes argument's specificity |
!important
Jumps to top of origin tier. Avoid unless: a11y overrides, third-party containment, framework utilities.
@layer
Explicit cascade ordering for large codebases — later layers win.
1.6.c Inheritance & Computed Styles
Inherited by default
Typography: font-family, font-size, font-weight, line-height, color, text-align, letter-spacing, list-style, cursor, visibility
NOT inherited
Layout/Box: margin, padding, border, width, height, background, display, position, overflow, flex, grid
Keyword values
| Keyword | Effect |
|---|---|
inherit | Force parent's computed value |
initial | CSS spec default |
unset | inherit if inheritable, initial if not |
revert | Browser (user-agent) default |
Computed value pipeline
Specified → Computed → Used → Actual (rendered)
Practical pattern
/* Set on root, inherit everywhere */
:root { font-family: system-ui, sans-serif; color: #1a1a2e; }
/* Fix form elements that break inheritance */
button, input, select, textarea { font: inherit; }
1.6.d Box Model
The four layers
┌──────── MARGIN ────────┐
│ ┌────── BORDER ──────┐ │
│ │ ┌──── PADDING ───┐ │ │
│ │ │ CONTENT │ │ │
│ │ └────────────────┘ │ │
│ └────────────────────┘ │
└────────────────────────┘
box-sizing
| Value | width includes |
|---|---|
content-box (default) | Content only (padding + border added on top) |
border-box | Content + padding + border (total = declared width) |
Always reset globally:
*, *::before, *::after { box-sizing: border-box; }
Margin collapsing
- Vertical margins of adjacent block siblings collapse (larger wins).
- Does not happen: horizontal margins, flex/grid children, BFC boundaries.
Margin auto
margin: 0 auto — horizontal centering for block elements.
Inline vs block
| Type | Width | Vertical margin/padding |
|---|---|---|
| Block | Full parent width | Affects layout |
| Inline | Content width | Does not push surrounding content |
| Inline-block | Content width | Affects layout |
1.6.e CSS Units
Unit reference
| Unit | Type | Relative to | Best for |
|---|---|---|---|
px | Absolute | Screen pixel | Borders, shadows, thin lines |
rem | Relative | :root font-size | Typography, spacing (scales with user pref) |
em | Relative | Element's own font-size | Component-internal spacing |
% | Relative | Parent dimension | Fluid widths |
vw / vh | Relative | Viewport width/height | Full-screen sections |
dvh | Relative | Dynamic viewport (mobile-safe) | Mobile full-height |
ch | Relative | Width of 0 glyph | Line width (max-width: 70ch) |
rem vs em
rem | em | |
|---|---|---|
| Reference | Root (stable) | Element (local) |
| Compounding | Never | Nested values multiply |
| Default choice | Yes | Only for component-internal scaling |
Accessibility
rem respects user font-size preferences; px does not. WCAG 1.4.4 requires text resizable to 200%.
1.6.f Modern CSS Functions
clamp(min, preferred, max)
font-size: clamp(1rem, 2.5vw, 2rem);
width: clamp(320px, 90%, 1200px);
Returns preferred, constrained between min and max.
min(a, b) — caps at maximum
width: min(100%, 400px); /* never wider than 400px */
max(a, b) — enforces floor
width: max(250px, 25%); /* at least 250px */
calc() — arithmetic with mixed units
width: calc(100% - 250px);
All functions accept mixed units (rem, vw, px, %).
Fluid typography
body { font-size: clamp(1rem, 0.875rem + 0.5vw, 1.25rem); }
Use rem bounds for accessibility.
1.6.g CSS Variables
Syntax
:root { --color-primary: #2563eb; }
.button { background: var(--color-primary); }
.fallback { color: var(--text, #333); }
Key properties
- Inherit down the DOM tree.
- Override at any scope (
.dark-theme { --color-primary: #60a5fa; }). - JS-updatable:
document.documentElement.style.setProperty('--x', val). - vs preprocessors: CSS vars are runtime; Sass vars are compile-time.
Theming pattern
:root { --bg: #fff; --text: #1a1a2e; }
[data-theme="dark"] { --bg: #0f172a; --text: #e2e8f0; }
body { background: var(--bg); color: var(--text); }
1.6.h Design Systems
Anatomy
| Layer | Contains |
|---|---|
| Principles | Brand values, accessibility commitments |
| Tokens | Colors, spacing, typography, radii, shadows |
| Components | Buttons, cards, forms — with states, variants, a11y |
| Documentation | Usage guidelines, do/don't examples |
Why systems matter
Prevents: 200 shades of gray, inconsistent spacing, specificity wars, brittle one-off styles.
Anti-patterns
- Hardcoded values alongside tokens
- No semantic layer (using
--blue-500in components directly) - Too many tokens (decision fatigue)
1.6.i Design Tokens
Three tiers
Primitive: --blue-500: #2563eb ← "this value exists"
Semantic: --color-primary: --blue-500 ← "primary = this blue"
Component: --button-bg: --color-primary ← "buttons use primary"
Token categories
Colors · Spacing · Typography · Border radius · Shadows · Breakpoints · Motion · Z-index
Spacing system (4px base)
| Token | Value | Use |
|---|---|---|
--space-1 | 0.25rem (4px) | Tiny gaps |
--space-2 | 0.5rem (8px) | Compact padding |
--space-4 | 1rem (16px) | Default spacing |
--space-8 | 2rem (32px) | Section spacing |
--space-16 | 4rem (64px) | Hero padding |
Color contrast
- 4.5:1 for normal text
- 3:1 for large text (≥18pt or ≥14pt bold)
Platform distribution
tokens.json → CSS custom properties
→ Sass variables
→ iOS constants
→ Android resources
→ Tailwind config
One-liner definitions (25+ terms)
| Term | One-liner |
|---|---|
| Selector | Pattern that targets element(s) to style. |
| Declaration | property: value; — what to change and to what. |
| Specificity | Weight that determines which competing rule wins. |
| Cascade | Algorithm resolving conflicts: origin → specificity → source order. |
| Inheritance | Child inheriting a property value from its parent. |
| Computed value | Final resolved value after cascade, inheritance, and unit resolution. |
| Box model | Content + padding + border + margin layers around every element. |
border-box | box-sizing where width includes content + padding + border. |
| Margin collapsing | Adjacent vertical margins merge (larger wins, not additive). |
rem | Relative unit based on root font-size — scales with user preference. |
em | Relative unit based on element's own font-size — compounds when nested. |
vw / vh | 1% of viewport width / height. |
dvh | Dynamic viewport height — adjusts for mobile address bar. |
ch | Width of the 0 glyph — useful for line width constraints. |
clamp() | clamp(min, preferred, max) — fluid value with bounds. |
min() | Returns the smallest of its arguments (caps at max). |
max() | Returns the largest of its arguments (enforces floor). |
calc() | Arithmetic with mixed CSS units. |
| Custom property | --name variable defined in CSS, consumed via var(--name). |
:root | Pseudo-class targeting <html> — common home for global variables. |
:has() | Parent selector — selects elements based on their descendants. |
:where() | Selector list with zero specificity — ideal for overridable defaults. |
@layer | Cascade layer — explicit ordering of style priority. |
| Design system | Shared vocabulary of constraints, tokens, components, and docs. |
| Design token | Named, platform-agnostic design decision (color, spacing, etc.). |
| Primitive token | Raw palette value (--blue-500). |
| Semantic token | Role-based mapping (--color-primary). |
| Component token | Scoped binding (--button-bg). |
Master workflow — CSS fundamentals stack
- Selectors target elements → cascade determines which rule wins.
- Specificity scores: inline > ID > class > element.
- Inheritance flows typography down the tree; box properties don't inherit.
- Box model (
border-box) governs element sizing: content + padding + border. - Units (
rem,em,%,vw) make layouts scale with user preferences and viewports. - CSS functions (
clamp,min,max) enable fluid responsive design. - Custom properties (
--var) centralize values; enable theming and runtime updates. - Design systems constrain choices to tokens → consistency across the product.
- Design tokens (primitive → semantic → component) are the single source of truth.
- All layers connect: tokens → custom properties → components → cascade → pixels.
End of 1.6 quick revision.