CSS Foundations
CSS (Cascading Style Sheets) controls the visual presentation of HTML. Before learning Tailwind (Module 2), you need to understand what CSS actually does — because Tailwind is just CSS with pre-built class names.
How CSS Works
CSS rules follow this structure:
selector {
property: value;
}
/* Target all paragraphs */
p {
color: #374151;
font-size: 1rem;
line-height: 1.6;
}
/* Target by class */
.card {
background-color: white;
border-radius: 0.5rem;
padding: 1.5rem;
}
/* Target by ID */
#hero {
min-height: 100vh;
}
CSS Custom Properties (Variables)
This is how modern CSS handles theming and reuse — no pre-processor needed:
/* Define in :root for global access */
:root {
/* Colors */
--color-primary: #3b82f6;
--color-primary-dark: #1d4ed8;
--color-text: #111827;
--color-text-muted: #6b7280;
--color-bg: #ffffff;
--color-bg-subtle: #f9fafb;
/* Spacing scale */
--space-1: 0.25rem;
--space-2: 0.5rem;
--space-4: 1rem;
--space-8: 2rem;
--space-16: 4rem;
/* Typography */
--font-sans: 'Inter', system-ui, sans-serif;
--font-mono: 'JetBrains Mono', monospace;
--text-base: 1rem;
--text-lg: 1.125rem;
--text-xl: 1.25rem;
--text-2xl: 1.5rem;
/* Border radius */
--radius-sm: 0.25rem;
--radius-md: 0.5rem;
--radius-lg: 1rem;
}
/* Use the variables */
.btn-primary {
background-color: var(--color-primary);
color: white;
padding: var(--space-2) var(--space-4);
border-radius: var(--radius-md);
font-family: var(--font-sans);
}
.btn-primary:hover {
background-color: var(--color-primary-dark);
}
Dark Mode with Custom Properties
:root {
--color-bg: #ffffff;
--color-text: #111827;
}
/* Override when OS is in dark mode */
@media (prefers-color-scheme: dark) {
:root {
--color-bg: #111827;
--color-text: #f9fafb;
}
}
body {
background-color: var(--color-bg);
color: var(--color-text);
}
The Box Model
Every element is a box with four layers:
margin
border
padding
content
/* box-sizing: border-box makes padding/border NOT add to total width */
/* Put this at the top of every stylesheet */
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.card {
width: 300px;
padding: 1.5rem; /* space inside the box */
border: 1px solid #e5e7eb;
margin: 1rem; /* space outside the box */
}
Selectors You Must Know
/* Element */
h1 { }
/* Class */
.card { }
/* ID (use sparingly) */
#main-header { }
/* Descendant — any p inside .card */
.card p { }
/* Direct child only */
.nav > li { }
/* Adjacent sibling */
h2 + p { }
/* Pseudo-class */
a:hover { }
input:focus { }
li:first-child { }
li:last-child { }
li:nth-child(2) { }
/* Pseudo-element */
p::first-line { }
.card::before {
content: '';
display: block;
}
/* Attribute selector */
input[type="email"] { }
a[href^="https"] { } /* href starts with https */
Specificity (Why Your Styles Don't Apply)
When two rules target the same element, the more specific one wins:
| Selector | Specificity |
|---|---|
* | 0 |
p | 1 |
.card | 10 |
#header | 100 |
Inline style="" | 1000 |
!important | Nuclear option (avoid) |
/* Specificity: 10 + 1 = 11 */
.card p {
color: blue;
}
/* Specificity: 1 — loses to above */
p {
color: red;
}
Keep specificity low
Rely on classes (specificity 10) for styling. Avoid IDs and !important. Flat, low-specificity CSS is easier to override and maintain.
Typography
body {
font-family: 'Inter', system-ui, -apple-system, sans-serif;
font-size: 16px; /* base size */
line-height: 1.5; /* comfortable reading */
color: #111827;
}
h1 {
font-size: 2.5rem;
font-weight: 700;
line-height: 1.2; /* tighter for headings */
letter-spacing: -0.02em;
}
/* fluid typography — scales with viewport */
h1 {
font-size: clamp(1.75rem, 4vw, 3rem);
}
Activity
- Create
styles.csslinked to yourindex.htmlfrom the previous lesson - Add a CSS reset at the top (
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }) - Define at least 6 CSS custom properties in
:root - Use those variables to style your page
- Add dark mode support via
prefers-color-scheme - Style the nav, headings, cards, and footer
Key Takeaways
- Use
box-sizing: border-boxand a CSS reset on every project - Define colors, spacing, and typography as CSS custom properties in
:root - Keep specificity low — rely on classes, avoid IDs for styling
prefers-color-schemelets you support dark mode with zero JavaScript