Why this session exists (and what it honestly is)
Full CSS is a deep discipline - layout systems, animation, a whole cascade of rules about rules. This is deliberately a STARTER session: the smallest slice of CSS that delivers the biggest visible win on your page. When you want the deep end, MDN's Styling basics path continues exactly where today stops. One mechanical note: the playgrounds below put CSS in a <style> element right next to the HTML so you can see both halves together; on your real project it goes in the head, then migrates to a linked file in Demo 2.
CSS in one idea: selector { property: value } 7 min live
Session 1 dissected one HTML element and you had the whole language. Same trick today: one ruleset, fully dissected, and you can read every stylesheet on the internet. WHO to style, WHAT to change, what to change it TO.
LiveYour first ruleset3 min▶
A rule targeting body styles the whole page at once, because most text properties inherit downward - set the font on the body and every paragraph, list, and heading follows. Watch one rule change everything:
<style>
body {
font-family: Georgia, serif;
color: darkslategray;
}
</style>
<h1>Hello, CSS</h1>
<p>One ruleset and the whole page changes clothes.
The HTML underneath did not change at all.</p>
Where can CSS live? Three homes, one verdict each:
- Inline - a
styleattribute on one element. Avoid: unfindable, unreusable, overrides everything. - A
<style>element in the head - fine for learning and one-page experiments. Today's playgrounds live here. - A linked .css file -
<link rel="stylesheet" href="styles.css">in the head. The grown-up way: one file styles every page of a site. Demo 2 moves you there.
LiveElement selectors, and the cascade in one paragraph3 min▶
The simplest selector is an element name: p grabs every paragraph, h2 every second-level heading. One rule, every match - the same power a good regex has over a text file.
<style>
h2 { color: darkred; }
p { line-height: 1.6; }
</style>
<h2>Every h2 obeys</h2>
<p>One rule styles <strong>every</strong> matching
element on the page, present and future.</p>
<h2>This one too</h2>
<p>No copy-paste styling, ever.</p>
The cascade, one paragraph, no math: when two rules disagree, the more specific selector wins (a class beats a bare element name), and among equals, the later one wins. That is genuinely enough for this course - if you ever find yourself fighting a style, write a slightly more specific selector or move your rule later, and read the full cascade story on MDN when curiosity strikes.
The visible wins: color and type 6 min live
Ninety percent of "this page looks designed" is four dials: text color, background color, font, and line spacing. Plus one magic line that makes any page instantly readable.
LiveThe type makeover recipe4 min▶
- color and background-color take named colors (
darkslategray) or hex codes (#2B1D14) - hex is what design tools hand you. Soft dark on soft light beats pure black on pure white for long reading. - font-family takes a comma-separated wish list; the browser uses the first font it has. The system font stack below means "whatever this device uses natively" - free polish, zero downloads.
- line-height: 1.6 - the single cheapest readability upgrade in CSS. Default is cramped; 1.6 lets text breathe.
- max-width + margin auto - cap the line length and center the column. Full-window text lines are unreadable; this one-two is why every article site has a centered column.
<style>
body {
font-family: -apple-system, "Segoe UI", Roboto,
Helvetica, Arial, sans-serif;
color: #2B1D14;
background-color: #FDF6F0;
line-height: 1.6;
max-width: 34em;
margin: 0 auto;
}
h1 { color: #A6300F; }
</style>
<h1>A readable column</h1>
<p>Capped width, centered, breathing room between
lines, a font the device already loves. This is
most of what "professionally styled" means.</p>
This recipe is the whole first impression of a report. The same eight lines dropped into a Jupyter HTML export, a Streamlit custom style, or an emailed analysis turn "raw output" into "someone crafted this". Stakeholders cannot name why they trust the second one more - but they do.
Boxes, and a row of them 7 min live
Every element on a page is a rectangular box wearing up to four layers. Once you can see the layers, every spacing mystery you will ever debug becomes a question with exactly four possible answers.
LivePadding, margin, border - feel the difference3 min▶
Don't memorize the diagram - poke it. The playground below has both spacing dials on real boxes; the fastest way to own the box model is to turn one dial at a time and watch what moves.
<style>
p {
padding: 16px;
margin: 24px;
border: 3px solid darkred;
border-radius: 12px;
background-color: papayawhip;
}
</style>
<p>Box one - my padding is space inside my border.</p>
<p>Box two - the gap between us is our margins.</p>
- Background color fills the padding but not the margin - which is how you can always tell them apart on screen.
- border-radius rounds the corners; it is why the modern web looks friendly.
LiveClass selectors - style a family you choose2 min▶
Element selectors grab every p, but you rarely want EVERY p to be a card. A class attribute names your own family of elements, and a selector starting with a dot grabs exactly that family: .card in CSS matches class="card" in HTML. Define once, reuse everywhere - this is the pattern behind every design system you have ever used.
<style>
.card {
border: 1px solid darksalmon;
border-radius: 10px;
padding: 16px;
margin-bottom: 12px;
}
</style>
<div class="card">
<h3>Sales dashboard</h3>
<p>A weekend build with real numbers.</p>
</div>
<div class="card">
<h3>This course site</h3>
<p>Yes, these cards are the same trick.</p>
</div>
<div>
<h3>No class yet</h3>
<p>Not in the family, no card styling.</p>
</div>
LiveFlexbox starter - one row, solved2 min▶
Full CSS layout is Session 6-and-beyond territory, but one flexbox move is too useful to wait: display: flex on a container lays its children out in a row, gap spaces them evenly, and justify-content: space-between pushes the first and last child to opposite ends. That is the classic site header - name left, nav right - in three properties.
<style>
header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
border-bottom: 3px solid darkred;
}
nav { display: flex; gap: 16px; }
</style>
<header>
<strong>Phoebe Fu</strong>
<nav>
<a href="#about">About</a>
<a href="#projects">Projects</a>
<a href="#contact">Contact</a>
</nav>
</header>
Self-studyid vs class, descendant selectors, and one treat3 min read▶
- id vs class: ids are unique anchors (Session 2's #about) and CSS can target them with
#about- but ids win specificity fights so hard they cause them. House rule: ids for anchors, classes for styling. - Descendant selectors:
nav a(with a space) means "links INSIDE a nav" - style the menu links without touching links in your paragraphs. Read right to left: a, inside nav. - Specificity fights: if a style refuses to apply, something more specific is winning. Resist the urge to pile on
!important- inspect the element (Demo 3), find the winning rule, and write yours smarter. Every CSS veteran learned this the loud way. - One treat:
a:hover { color: darkred; }styles links only while the mouse is over them. Your first taste of interactive CSS - one line, try it on your nav tonight.
Style your page, top to bottom ★ 9 min · follow along
Everything from Parts 1-3 lands on your real page in one pass. A style element in the head for now - Demo 2 moves it out.
In your index.html head, add an empty <style> element below the title. All of today's CSS goes inside it.
The body rule first: the system font stack, a soft text color, a soft background, line-height: 1.6, max-width: 40em, margin: 0 auto, and padding: 0 16px so the text never touches the window edge. Save, reload - biggest visual jump of the course.
Headings next: give h1 and h2 an accent color you like. One accent color, used consistently, reads as a brand; five read as a fruit salad.
The header row: header { display: flex; justify-content: space-between; align-items: center; } plus nav ul { display: flex; gap: 16px; list-style: none; padding: 0; } - your Session 3 regions just became styling hooks, exactly as promised.
Cards: add class="card" to each project entry in your Projects section, then write one .card rule with border, border-radius, padding, and margin-bottom. Two projects, one rule.
Save, reload, and compare against your Session 1 memory of the same page. Same honest HTML underneath - that is the whole point of keeping structure and style separate.
Graduation: the linked stylesheet ★ 5 min · follow along
The style element was training wheels. Real sites keep CSS in its own file so every page can share it - the move takes two minutes and the proof of success is that nothing changes.
Create a new file next to index.html called styles.css. Cut everything from INSIDE your style element (not the tags themselves) and paste it there. A .css file is pure rules - no HTML tags anywhere in it.
Delete the now-empty style element and replace it with <link rel="stylesheet" href="styles.css"> - in the head, right where Session 2's finished head left room for it.
Save both files, reload. The page looks EXACTLY the same - that is success. If it suddenly lost all styling, check the href spelling and that both files sit in the same folder: it is a relative path, same rules as images.
Feel the payoff: when your site grows a second page, one link line gives it the entire look. One file to rule every page.
Steal like a designer ★ 3 min · build your own
Every site you admire publishes its design decisions in plain sight - devtools reads them. Ethical theft: take the palette and type choices, not the content.
Open a site whose look you love. Right-click its body text and choose Inspect - the Styles panel shows every rule hitting that element, winners on top.
Read three decisions: the font-family stack, the text color, and the line-height. Click any color swatch to see the hex code.
Edit the values live in the panel - devtools changes are a scratchpad, gone on reload. Nothing you break is real.
Take one hex color and one type decision home to your styles.css. Your palette, upgraded by observation - the same skill as reading a good notebook to improve your own.
Try it yourself - this week ◐ 30-45 min total
- Style your Session 4 work: give
tablecollapsed borders (border-collapse: collapse) and padded cells, and give your form's inputs some padding. Notice how much of it is just the box model again. - Add the self-study treat:
a:hoverwith your accent color on the nav links. One line, disproportionate delight. - Palette hunt: inspect three sites you trust, collect their body text colors, and pick your favorite pairing of text + background for your own page.
- Break-and-fix: set your body max-width to 10em, reload, feel the pain, put it back. Then set line-height to 1 and do the same. Bad values teach faster than good ones.
- Bring to Session 6: your styled page plus one thing that still bugs you about it - polish, validation, and shipping to a real URL are next.
Official sources covered
This session teaches the working core of MDN's CSS styling basics - deliberately the starter slice, chosen for visible payoff. The full module (values and units, sizing, overflow, images in CSS, the complete cascade) is the honest deep end, linked here for when you want it.
Three questions before you go 🎯 ◐ 90 seconds
1 · Your cards feel cramped - the text touches the border. Which dial do you turn?
Space between content and its own border is padding. Margin would move the cards apart from each other but the text would still hug the frame.
2 · You wrote class="card" on three divs. Which selector styles them?
Dot means class, hash means id, bare name means element type. A bare "card" would look for a <card> element that does not exist.
3 · Where does the link element for styles.css belong?
The stylesheet link is about the page, not on it - head territory from Session 1. Browsers want styles known before they paint the body.