Foundations · Lesson 1/9

HTML & CSS — Your First Web Page

45 min 4 exercises 1 quiz

What you'll learn

By the end of this lesson you will:

  • Understand what HTML and CSS actually are (no scary words)
  • Write a real web page with your own hands, using semantic tags
  • Master the CSS box model — padding, border, and margin, precisely
  • Style it with colors, spacing, and rounded corners
  • Build a real layout with Flexbox — the tool behind almost every navbar and card grid on the web
  • Pass hands-on exercises checked automatically by the browser, including a live layout challenge

You don't need to install anything. The code runs right here on this page.

Imagine a house 🏠

Think of a web page like a house:

  • HTML is the walls and rooms. It says: "here is a title, here is a paragraph, here is a picture." It's the structure.
  • CSS is the paint and furniture. It says: "make the title green, put space around the picture, round the corners." It's the style.

The browser (Chrome, Safari…) is the builder. It reads your HTML and CSS like instructions and builds the page you see.

An HTML file is just text with special labels called tags. A tag looks like this: <h1> — the name inside angle brackets. Most tags come in pairs: an opening tag <h1> and a closing tag </h1> (note the slash). Whatever sits between them is what shows on the page:

<h1>Hello!</h1>

That's it. That's HTML. You already know it.

Here is a complete tiny web page. <h1> is the biggest heading, <p> is a paragraph. Press "Try it yourself", change the text, then press Run and watch the preview update. Break it on purpose! You can't damage anything.

<!DOCTYPE html>
<html>
  <body>
    <h1>My first page</h1>
    <p>I am learning HTML. This is a paragraph.</p>
    <p>Each paragraph gets its own line.</p>
  </body>
</html>
Exercise 1

Your turn! Build a page about yourself. It must have:

  1. A big heading (<h1>) with your name
  2. At least one paragraph (<p>) about you

Write anything you like — the checker only looks at the structure.

Lists and links 📋🔗

Two more building blocks you'll use every single day:

A list is like a shopping list. <ul> means "unordered list" (bullet points), and every item goes inside <li>:

<ul>
  <li>Pizza</li>
  <li>Dates</li>
  <li>Kabsa</li>
</ul>

A link takes you to another page. The tag is <a> and the destination goes in something called an attribute — extra info written inside the opening tag:

<a href="https://google.com">Go to Google</a>

href is the attribute (the address), and "Go to Google" is the text people click on.

Exercise 2

Build a "My favorite things" page:

  1. A <ul> list with at least 3 <li> items
  2. A link (<a>) to any website — don't forget the href attribute

Semantic HTML — tags with meaning 🏷️

So far you've used generic tags. But HTML has special tags that describe what a section of the page means, not just how it looks. These are called semantic tags:

<header>   <!-- the top of the page: logo, title -->
<nav>      <!-- the navigation links -->
<main>     <!-- the main content, once per page -->
<section>  <!-- a themed group of content -->
<article>  <!-- a self-contained piece, like a blog post -->
<footer>   <!-- the bottom: copyright, links -->

You could build a whole page out of <div> alone — the browser wouldn't complain. So why bother?

  1. Screen readers depend on it. A blind user's screen reader announces "navigation" when it hits a <nav>, letting them jump straight to it. A page built entirely of <div>s is a maze with no signposts for them.
  2. Search engines read it. Google gives more weight to text inside <article> and <h1> than inside a meaningless <div> — semantic tags are a free SEO boost.
  3. Other developers (including future you) read it faster. <footer> instantly tells a reader of your code what that block is, no comment needed.

Rule of thumb: reach for a semantic tag first. Only fall back to a plain <div> when nothing else fits.

Now let's paint the house — CSS 🎨

Plain HTML looks like a document from 1995. CSS (Cascading Style Sheets) is how we make it beautiful.

A CSS rule has three parts:

h1 {
  color: green;
}
  1. Selector (h1) — who gets styled ("all h1 headings")
  2. Property (color) — what changes
  3. Value (green) — how it changes

Think of it like giving orders to a painter: "All the headings → paint them green."

The easiest place to write CSS is inside a <style> tag in your page. You can also target your own custom groups using a class: give any tag class="card", then select it in CSS with a dot: .card { ... }.

The most useful properties to memorize first:

  • color — text color
  • background — background color
  • padding — space inside the box
  • margin — space outside the box
  • border-radius — rounded corners
  • font-size — text size

Same HTML idea, but now with a <style> block. Notice .card — the dot means "everything with class='card'". Try changing the colors and the border-radius, then press Run.

<!DOCTYPE html>
<html>
  <head>
    <style>
      body {
        font-family: sans-serif;
        background: #f0f4f8;
      }
      h1 {
        color: #059669;
      }
      .card {
        background: white;
        padding: 20px;
        border-radius: 12px;
        box-shadow: 0 2px 8px rgba(0,0,0,0.1);
      }
    </style>
  </head>
  <body>
    <h1>Styled page</h1>
    <div class="card">
      <p>This box has padding, rounded corners and a shadow.</p>
    </div>
  </body>
</html>
Exercise 3

Style the card! The HTML is ready — write CSS inside the <style> tag so that the .card box has:

  1. A background color (any color except transparent)
  2. Rounded corners of at least 8px (border-radius)
  3. Inner spacing of at least 12px (padding)

The box model — every element is a box 📦

Here's the single most important mental model in CSS: every HTML element is a rectangular box, made of four layers, from the inside out:

┌─────────────────────────────────┐
│           margin (outside)       │
│  ┌─────────────────────────────┐ │
│  │        border                │ │
│  │  ┌───────────────────────┐  │ │
│  │  │     padding            │  │ │
│  │  │  ┌─────────────────┐  │  │ │
│  │  │  │     content      │  │  │ │
│  │  │  └─────────────────┘  │  │ │
│  │  └───────────────────────┘  │ │
│  └─────────────────────────────┘ │
└─────────────────────────────────┘
  • Content — the actual text or image.
  • Padding — space between the content and the border (increasing it makes the box bigger, pushing the border outward).
  • Border — a visible (or invisible) line around the padding.
  • Margin — space outside the border, pushing away other elements.

The gotcha every beginner hits: by default, width: 200px sets the width of the content only — padding and border get added on top, so a box with width: 200px; padding: 20px; border: 2px; actually renders 244px wide. This surprises everyone at least once.

The fix, used in almost every professional stylesheet:

* {
  box-sizing: border-box;
}

This changes the rule so width includes padding and border — what you set is what you get. Add this once at the top of your CSS and the surprise disappears forever.

Flexbox — real layout, not guesswork 📐

Before Flexbox, lining up boxes side by side (like a navbar, or a row of cards) required fragile hacks. Flexbox fixed this: give a container display: flex and it automatically arranges its children in a row (or column), and gives you simple controls for spacing and alignment.

.container {
  display: flex;             /* turn on flexbox */
  justify-content: space-between; /* spacing along the row */
  align-items: center;       /* alignment across the row */
  gap: 16px;                 /* space between items */
}

Think of .container as a shelf, and its direct children as books on it:

  • display: flex — "arrange my children in a row" (the default direction).
  • justify-content — how items spread out along the row: flex-start (packed left), center, space-between (edges touch the container, gaps spread evenly between), space-around.
  • align-items — how items line up across the row: flex-start (top), center, stretch (fill the height).
  • gap — clean, even spacing between items — no more fiddly margins on every child.

This one tool builds navbars, card grids, centered modals, and sidebars — probably 80% of the layouts you'll ever build.

A real navbar, built with two nested flex containers: the outer one spaces the logo and links apart (space-between), the inner one lines up the links with a gap. Try changing justify-content to center and watch everything move.

<!DOCTYPE html>
<html>
  <head>
    <style>
      body { font-family: sans-serif; margin: 0; }
      .navbar {
        display: flex;
        justify-content: space-between;
        align-items: center;
        background: #0D1117;
        padding: 16px 24px;
      }
      .navbar .logo { color: #10b981; font-weight: bold; }
      .navbar .links { display: flex; gap: 20px; }
      .navbar a { color: white; text-decoration: none; }
    </style>
  </head>
  <body>
    <div class="navbar">
      <div class="logo">MySite</div>
      <div class="links">
        <a href="#">Home</a>
        <a href="#">About</a>
        <a href="#">Contact</a>
      </div>
    </div>
  </body>
</html>
Exercise 4

Build a row of pricing cards. The HTML has 3 .card divs inside a .row container. Make .row:

  1. display: flex
  2. gap of at least 16px between the cards

The cards should end up in a neat horizontal row with visible space between them.

Real-world case study: this exact site 🔍

You don't need to imagine a real example — you're using one right now. Open your browser's DevTools (press F12, or right-click → "Inspect"), click the arrow-cursor icon, then click on the top navigation bar of this very page.

You'll find the top nav is built almost exactly like the pricing-card exercise you just solved: a flex container spacing the logo on one side and the links + buttons on the other, with gap handling the spacing between the nav links. The rounded cards you see on the roadmaps and certifications pages use the same border-radius + padding + box-shadow combination from the card exercise earlier in this lesson.

This is the actual, honest truth about frontend work: the fundamentals you just practiced — box model, flexbox, semantic tags — are not "toy" exercises. They are literally what every production website, including this one, is built from.

Quick quiz

Question 1 of 7

What is HTML responsible for?

Question 2 of 7

Which is a correct closing tag?

Question 3 of 7

In CSS, what selects everything with class="card"?

Question 4 of 7

padding is the space…

Question 5 of 7

Why use <nav> instead of a plain <div> for navigation links?

Question 6 of 7

With the default box-sizing, if width: 200px and padding: 20px, how wide does the box actually render?

Question 7 of 7

What does display: flex do to a container's direct children?

You did it! 🎉

Today you:

  • Built real pages with headings, paragraphs, lists and links
  • Used semantic tags (<nav>, <header>, <footer>) that screen readers and search engines understand
  • Mastered the box model — content, padding, border, margin — and the box-sizing: border-box fix
  • Styled a card with background, padding and rounded corners
  • Built a real flexbox layout — a navbar and a row of pricing cards
  • Learned the three-part anatomy of every CSS rule

What's next? CSS Grid (for two-dimensional layouts) is worth exploring on your own via the freeCodeCamp course in the Resources tab — then move to the JavaScript lesson to make your pages come alive.

Practice idea: rebuild the navbar demo from memory tomorrow, then try turning it into a mobile-friendly layout. If you can, you've truly learned it.