1. What CSS Actually Does
CSS (Cascading Style Sheets) controls the visual presentation of HTML. HTML defines what things are. CSS defines how they look: colors, fonts, spacing, layout, animations.
Without CSS, every website looks like a plain academic paper from 1995. With CSS, the same HTML can look like a SaaS landing page, a portfolio, or an e-commerce storefront.
The Separation Principle
Professional developers keep HTML and CSS in separate files. HTML = structure. CSS = presentation. Never use inline styles (style="color: red") in production — it's impossible to maintain and overrides everything. You'll understand why when we cover specificity.
2. Three Ways to Add CSS
| Method | How | When to Use |
|---|---|---|
| External stylesheet ✅ | <link rel="stylesheet" href="style.css"> in <head> |
Always. This is the professional standard. |
| Internal stylesheet | <style> block inside <head> |
Quick prototyping, single-page demos only. |
| Inline styles ❌ | <p style="color: red"> |
Almost never. Breaks separation, unmaintainable. |
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Portfolio</title>
<link rel="stylesheet" href="style.css">
</head>
3. CSS Anatomy: Selectors, Properties, Values
Every CSS rule follows this pattern:
selector {
property: value;
property: value;
}
- Selector — what to style (which HTML element)
- Property — which aspect to change (color, font-size, margin)
- Value — how to change it (red, 16px, 2rem)
/* Select ALL <h1> elements */
h1 {
color: #1d1d1f;
font-size: 2.5rem;
font-family: 'Inter', sans-serif;
}
4. Selectors — Targeting the Right Elements
Selectors are the aiming system of CSS. You must learn these four cold:
| Selector | Syntax | Selects |
|---|---|---|
| Element | p { } |
All <p> tags on the page |
| Class | .card { } |
All elements with class="card" |
| ID | #hero { } |
The one element with id="hero" |
| Universal | * { } |
Every element on the page |
Class vs. ID: The Professional Rule
Use classes for styling. IDs are unique — only one per page — and have very high specificity, making them hard to override. Professional codebases use classes for 99% of CSS. IDs are reserved for JavaScript hooks and anchor links. If you see yourself writing #header { }, stop and use .header { } instead.
Combining Selectors
| Pattern | Syntax | Meaning |
|---|---|---|
| Descendant | nav a { } |
All <a> tags inside a <nav> |
| Multiple | h1, h2, h3 { } |
All h1, h2, and h3 tags |
| Chained | .card.featured { } |
Elements with both classes |
🛝 Try It: Selectors Playground
Edit the CSS below and watch the preview update instantly. Try changing the color of just the .highlight class.
5. Colors in CSS
There are multiple ways to specify colors. You should know all three:
| Format | Example | When to Use |
|---|---|---|
| Named | color: red; |
Quick prototyping only. Limited palette. |
| Hex | color: #8b5cf6; |
Most common in production. 6 hex digits = R G B. |
| RGB / RGBA | color: rgba(139, 92, 246, 0.8); |
When you need transparency (the alpha channel). |
| HSL | color: hsl(262, 90%, 66%); |
Most intuitive: Hue (color), Saturation, Lightness. Great for building palettes. |
6. Units: px, rem, em, %
CSS uses different units for different purposes. Choosing the right unit is a hallmark of a professional developer:
| Unit | Meaning | Use For |
|---|---|---|
px |
Pixel — absolute, fixed size | Borders, shadows, tiny details |
rem |
Relative to the root font size (usually 16px) | Font sizes, spacing, padding. The go-to unit. |
em |
Relative to the parent's font size | Internal component spacing that should scale with text |
% |
Percentage of the parent element | Widths, responsive layouts |
vh / vw |
Viewport height / width (1vh = 1% of browser height) | Full-screen hero sections, modals |
The rem Rule
Use rem for almost everything — font sizes, margins, paddings. The default root font size is 16px, so 1rem = 16px, 1.5rem = 24px, 2rem = 32px. If the user increases their browser's default font size (for accessibility), rem values scale automatically. px does not. This is why rem is the professional choice.
7. The Box Model — The Most Important Concept in CSS
Every HTML element is a rectangular box. The box model describes the layers that make up that box, from inside out:
┌──────────────────────────────────────┐
│ MARGIN │ ← Space OUTSIDE the border
│ ┌────────────────────────────────┐ │ (pushes other elements away)
│ │ BORDER │ │ ← Visible line around the element
│ │ ┌──────────────────────────┐ │ │
│ │ │ PADDING │ │ │ ← Space INSIDE the border
│ │ │ ┌────────────────────┐ │ │ │ (between border and content)
│ │ │ │ CONTENT │ │ │ │ ← Your text, images, etc.
│ │ │ │ (width × height) │ │ │ │
│ │ │ └────────────────────┘ │ │ │
│ │ └──────────────────────────┘ │ │
│ └────────────────────────────────┘ │
└──────────────────────────────────────┘
Box Model Properties
width and height.border: 1px solid #ccc;.card {
width: 300px;
padding: 1.5rem; /* all 4 sides */
border: 1px solid #e5e5e7;
margin: 2rem 0; /* top/bottom: 2rem, left/right: 0 */
border-radius: 12px; /* rounded corners */
}
The box-sizing Fix
By default, width: 300px sets only the content width. Padding and border are added on top, making the element wider than 300px. This is insane behavior. Every professional project adds this fix at the top of their CSS:
* {
box-sizing: border-box; /* padding and border included in width */
margin: 0;
padding: 0;
}
box-sizing: border-box
Without this, every width calculation is a headache. With it, width: 300px means the total width is 300px, including padding and border. Every CSS framework, every professional project, every component library includes this reset. Do it once, forget about it forever.
Source: MDN — The CSS Box Model
🛝 Try It: Box Model Playground
Edit the padding, margin, and border values. Watch how they change the box. Try making the padding 3rem and see what happens.
8. Typography — Making Text Look Professional
Bad typography is the fastest way to make a website look amateur. Here are the properties that matter:
body {
font-family: 'Inter', system-ui, sans-serif;
font-size: 1rem; /* 16px base */
line-height: 1.6; /* breathing room between lines */
color: #1d1d1f; /* near-black, not pure #000 */
}
h1 {
font-size: 2.5rem; /* 40px */
font-weight: 700; /* bold */
letter-spacing: -0.02em; /* tighten large text */
line-height: 1.1; /* tighter for headings */
}
p {
margin-bottom: 1.25rem; /* space between paragraphs */
max-width: 65ch; /* ideal reading width (~65 characters) */
}
- Never use pure black (
#000). Use near-black (#1d1d1f). It's easier on the eyes. - Body
line-height: 1.5to1.7. Headings:1.1to1.3. - Use Google Fonts for professional typefaces. Popular choices: Inter, DM Sans, Plus Jakarta Sans.
- Limit your page to 2 fonts maximum. More looks chaotic.
Loading a Google Font
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap"
rel="stylesheet">
9. The Cascade & Specificity — Which Style Wins?
When two CSS rules target the same element, which one wins? CSS has a scoring system called specificity. Think of it as a 3-digit number:
| Selector Type | Score | Example |
|---|---|---|
Element (p, h1, div) |
0-0-1 | p { color: gray; } |
Class (.card, .active) |
0-1-0 | .card { color: blue; } |
ID (#hero) |
1-0-0 | #hero { color: red; } |
Higher score wins. If scores tie, the last rule written wins. And !important overrides everything (but never use it — it's a code smell that means your selectors are broken).
/* Score: 0-0-1 — element selector */
p { color: gray; }
/* Score: 0-1-0 — class selector (WINS over element) */
.intro { color: blue; }
/* Score: 1-0-0 — ID selector (WINS over everything) */
#welcome { color: red; }
/* A <p class="intro" id="welcome"> would be RED */
🛝 Try It: Specificity Battle
The text below has class="intro" and id="welcome". Edit the CSS to see which rule wins. Try removing the ID rule and watch the class take over.
10. Essential Beginner Properties
Here are the properties you'll use every single day. This is not a complete list — it's the ones that matter right now:
Must-Know Properties
rem)width style color (e.g., 1px solid #ccc)12px = modern, 50% = circle)max-width for responsive containers.left, center, rightInteractive Practice Zone
Test your understanding of CSS fundamentals.
.card { } select?rem instead of px for font sizes?<p> has both class="intro" and an element selector p { }, which style wins?box-sizing: border-box do?Quiz Completed!
Come back and retry this quiz tomorrow — spaced repetition builds permanent knowledge.
11. Fill in the Blank: Write a CSS Rule
Complete this stylesheet from memory. Each blank is one CSS keyword, property, or value.
12. Build Challenge: Style Your Portfolio
This is the most important part. You're going to take the semantic portfolio page from Lesson 2 and make it actually look good.
- Create a file called
practices/lesson4-style.css - Open your
practices/lesson2-portfolio.htmland add a<link>to your new CSS file in the<head> - Also add a Google Font link (use Inter)
- In your CSS file, write styles for:
- Global reset:
* { box-sizing: border-box; margin: 0; padding: 0; } - Body: Set
font-family,font-size,line-height,color,background-color - Container: Use a class
.containerwithmax-widthandmargin: 0 autoto center content - Header: Style the
headerwith padding, a bottom border - Navigation links: Style
nav a(use a descendant selector!) — change the color, remove the underline - Sections: Give each
sectionsome padding and margin - Footer: Style the
footerwith a top border, lighter text color
- Global reset:
- Open in browser and verify it looks clean and professional
Primary Source: For a deeper exploration of every CSS concept covered here, work through MDN: CSS Styling Basics. Also watch Kevin Powell's CSS channel — he's the best CSS teacher on the internet.
Finished the build? Stuck on something? Come back and show me your code — I'll review it and we'll move on to CSS layout (Flexbox).