learn-html-with-phoebe / Session 5 of 6
Learn HTML with Phoebe · Session 5 of 6

Enough CSS to be proud of your page

Four sessions of honest structure have been wearing browser defaults. Today the payoff: one new language with one grammar rule, and by the end your page has real typography, a readable column, cards, and a proper header row - styling you chose, not inherited.

🟠 New territory Total beginners welcome Data & AI folks too 45 min live + self-study depth
0-3 · Welcome 3-23 · Concepts (live cards) 23-40 · Three demos 40-45 · Q&A
Part 0

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.

Live - presented in session Self-study - read after class ★ Try it now Every example on this page is editable - type and watch
★ What you walk out with today The one CSS grammar rule (selector { property: value }), the three places CSS can live and which to use, color and typography that make a page feel designed, the box model that explains every spacing mystery, a reusable .card class, and a flexbox one-liner that puts your name and nav on one row. Your project page will look like you meant it.
Part 1 · covers MDN "What is CSS" + "Getting started with CSS"

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.

h1 { color : darkred ; } selector - WHO which elements this rule grabs property - WHAT the dial you are turning value - TO WHAT the new setting, ended with ; Same shape every time. A stylesheet is just a stack of these - visual rhyme with Session 1's element anatomy.
🔍 Click to zoom - one ruleset, fully dissected. All of CSS is this shape repeated.
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 style attribute 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.

Part 2 · covers MDN styling basics: colors + typography essentials

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>
Real world

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.

Part 3 · covers MDN box model + selectors (class) + a first taste of flexbox

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.

margin border padding content margin - space OUTSIDE pushes neighbors away; between boxes border - the visible edge 3px solid darkred; radius rounds it padding - space INSIDE pushes the border away from content content - the text itself what the element actually holds Plain-language rule: padding = breathing room inside the frame, margin = personal space between frames.
🔍 Click to zoom - the box model rings. Every "why is there a gap here" question ends at one of these four layers.
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.
Demo 1 of 3 · the running project gets dressed

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.

Demo 2 of 3

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.

Cache gotcha If a CSS change ever refuses to show up, the browser may be serving an old cached copy. Hard-reload (Cmd+Shift+R or Ctrl+Shift+R) before you doubt your code.
Demo 3 of 3

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.

Homework

Try it yourself - this week ◐ 30-45 min total

Source material

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.

✓MDN: What is CSS + Getting startedPart 1 - ruleset anatomy, the three homes for CSS, applying styles
✓MDN: Basic selectors (element + class)Parts 1 and 3 - element selectors, .class; id and descendant in self-study
✓MDN: Box modelPart 3 - content/padding/border/margin, felt live in the playground
✓MDN: Colors + text and font styling essentialsPart 2 - color, background, font stacks, line-height, the readable column
◐Flexboxstarter only - display:flex, gap, space-between; full layout is MDN's flexbox lesson
◐The full cascade, specificity, and layout systemsone honest paragraph today; MDN's CSS path continues from here
Check yourself

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.

Session 5 cheat sheet · pin this

The grammarselector { property: value; } - WHO, WHAT, TO WHAT. Semicolon after every declaration. All of CSS is this shape.
Three homesInline style attribute (avoid) · style element in head (learning) · linked styles.css via link rel="stylesheet" (the real way).
Cascade, no mathMore specific selector wins; among equals, later wins. Fighting a style? Get more specific or move your rule later.
Readable columnbody { max-width: 40em; margin: 0 auto; line-height: 1.6; padding: 0 16px; } - the one-line professional look.
System font stackfont-family: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; - native polish, zero downloads.
Box modelcontent → padding (inside the border) → border → margin (between boxes). Background fills padding, never margin.
Class recipeclass="card" in HTML, .card { } in CSS. Define once, reuse everywhere. Ids for anchors, classes for styling.
Flex starterdisplay: flex; gap: 16px; justify-content: space-between; - name left, nav right, done.