Skip to content

Lesson 1 — Guided lesson ​

3 hours with your teacher · Explore how a web page works

Today is about understanding what happens when you open a web page. You will make a small Travel Desk page using HTML and CSS, preview it with the Live Server extension in VS Code, and use the browser's developer tools to investigate it.

You do not need a framework, Node.js, npm, or a build tool. Today you will install a lightweight VS Code extension called Live Server to serve the page locally and reload it when you save changes. You do not need to write JavaScript in a file today. You will try a few small JavaScript expressions in the browser Console to see what the browser knows about your page.

Keep the companion reference nearby. It contains short explanations and fixes you can return to during the lesson and practice.

Your materials ​

MaterialUse it for
Guided lesson — this pageFollow the teacher's steps and build a small example
Companion referenceLook up HTML, CSS, forms, DOM, and browser tools
Independent practiceApply what you learned to a different brief during the next 3 hours

Before you begin ​

You need:

  • Visual Studio Code;
  • Chrome or Edge, with developer tools;
  • internet access to install one VS Code extension;
  • a folder on your computer where you can save your work.

We will install Live Server during the lesson. No account, terminal commands, npm packages, or project generator are required.

Learning objectives ​

By the end of this lesson, you should be able to:

  1. Describe what HTML, CSS, JavaScript, and the browser each do.
  2. Install the VS Code Live Server extension and preview an HTML file at a local http:// address.
  3. Recognize semantic HTML elements and use labels correctly in a form.
  4. Make a few basic CSS changes and see their effect at different screen widths.
  5. Explain the difference between your saved HTML file, the DOM, and the page you see.
  6. Use the Elements, Console, and Network panels in browser DevTools.
  7. Type simple expressions in the Console to inspect the page.
  8. Identify and fix a broken label/input relationship and a missing stylesheet.
  9. Explain what Live Server does and recognize the status of HTML/CSS requests in the Network panel.

Today's route ​

ActivityCheckpoint
Part 1 — How the browser builds a pageExplain the main layers
Part 2 — Make a page and install Live ServerPage runs at a localhost address
Part 3 — HTML structure and formsThe Travel Desk content is visible
Part 4 — Brief CSS refresherPage is readable on small and large screens
Part 5 — Inspect the DOM, Console, and NetworkFind elements and query them
Part 6 — Debugging experimentsFix a label and stylesheet issue
Part 7 — Independent checks and reviewExplain what you changed

Part 1 — What happens when you open a web page? ​

1.1 The jobs of HTML, CSS, JavaScript, and the browser ​

Imagine a page where someone can read information about a business trip and fill in a request form.

PartIts jobExample
HTMLGives content structure and meaningHeading, form, input, button
CSSControls appearance and layoutColors, spacing, widths
JavaScriptAdds logic and interactive behaviorCalculate a price, update a status, call an API
BrowserReads the page, draws it, and handles user interactionDisplays text, focuses fields, checks required inputs

A useful picture:

text
index.html ────┐
               ├── Browser ──> Page you see
style.css ────┘       │
                      ├── Builds the DOM
                      ├── Applies CSS
                      └── Provides built-in behaviors

JavaScript (from Lesson 2 onward)
can read and change the DOM.

Even without JavaScript, a browser already knows how to follow links, let people type into fields, and check some form constraints.

1.2 Source HTML and the DOM are not the same thing ​

Consider this HTML:

html
<main>
  <h1>Travel Desk</h1>
  <p>Plan your next journey.</p>
</main>

When the browser reads it, it creates an in-memory representation called the Document Object Model (DOM).

A simplified tree looks like:

text
Document
└── html
    └── body
        └── main
            ├── h1
            └── p

The DOM is not a second file. It is the browser's current representation of the page. Later, JavaScript will use this representation to find and change elements.

Remember this

HTML is what you saved. The DOM is what the browser built. The visible page is what the browser rendered.

Quick discussion ​

  • Which layer would you change to add a new field?
  • Which layer would you change to add space around a card?
  • Which layer would you use later to calculate a total from entered values?

Part 2 — Create a page and run it with Live Server ​

2.1 Create your lesson folder ​

  1. Open Visual Studio Code.
  2. Create a folder named lesson-01 somewhere you can find it again.
  3. Open that folder in VS Code using File → Open Folder.
  4. Create a file named index.html.
  5. Create another file named style.css.

Your folder should look like this:

text
lesson-01/
├── index.html
└── style.css

That is all we need.

2.2 Start with the smallest useful HTML document ​

Add this to index.html:

html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Travel Desk</title>
    <link rel="stylesheet" href="./style.css" />
  </head>
  <body>
    <h1>Travel Desk</h1>
    <p>Our first page is ready.</p>
  </body>
</html>

Save the file.

2.3 Install Live Server in VS Code ​

  1. In VS Code, open Extensions (click the Extensions icon, or press Ctrl+Shift+X on Windows/Linux).
  2. Search for Live Server.
  3. Select Live Server, published by Ritwick Dey (ritwickdey.LiveServer).
  4. Click Install. You only install the extension once on your computer.
  5. If asked, reload the VS Code window.

Not Vite or npm

Live Server is a VS Code extension, not a framework or a generated application. Our website still consists of just index.html and style.css.

2.4 Preview the page with Live Server ​

  1. Make sure the lesson-01 folder is open in VS Code.
  2. Find index.html in the Explorer panel.
  3. Right-click index.html and choose Open with Live Server. Alternatively, with the project open, use Go Live in the VS Code status bar.
  4. Your browser should open the page.

The address will look similar to:

text
http://127.0.0.1:5500/index.html

It might instead use localhost or a different port number. Use the address Live Server actually opens; do not type a fixed port from memory.

You should see the Travel Desk heading and one paragraph.

What does this address mean?

127.0.0.1 and localhost refer to your own computer. Live Server runs a small local HTTP server that sends your HTML and CSS files to the browser. We are not deploying a website or using an external backend.

2.5 Save a change and observe the reload ​

  1. In VS Code, change Our first page is ready. to a different sentence.
  2. Save index.html (Ctrl+S or Cmd+S).
  3. Watch the browser: Live Server should reload the page and display the new sentence automatically.

If it does not, refresh the browser manually and check the troubleshooting advice in the companion.

Checkpoint ​

  • Does the browser show Travel Desk?
  • Does the address begin with http://localhost or http://127.0.0.1, rather than file://?
  • Does saving an HTML change reload the page?
  • Can you point to Go Live or the status control used to stop Live Server?

Part 3 — Build the HTML content ​

We will replace the starter heading and paragraph with a small page that has navigation, a travel summary, and a form.

3.1 What do the semantic elements mean? ​

ElementUse it for
<header>Introductory content
<nav>Navigation links
<main>The page's primary content
<section>A group of related content
<article>One self-contained item, such as a trip card
<h1>, <h2>, <h3>Headings and their hierarchy
<form>Controls for entering and submitting information
<label>An accessible label for a form control
<input>, <select>Native form controls
<button>An action
<footer>Closing information

Choose the element that matches the meaning of the content. Use CSS to control its appearance.

3.2 Replace index.html ​

Replace the contents of index.html with the following. We will discuss the important parts afterward.

html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Travel Desk — Lesson 1</title>
    <link rel="stylesheet" href="./style.css" />
  </head>
  <body>
    <header class="site-header">
      <div class="container">
        <p class="brand">Travel Desk</p>
        <nav aria-label="Main navigation">
          <a href="#featured-trip">Featured trip</a>
          <a href="#request">Request form</a>
        </nav>
      </div>
    </header>

    <main class="container">
      <h1>Plan your next business trip</h1>
      <p>Explore a sample trip and try a demonstration form.</p>

      <section id="featured-trip" aria-labelledby="trip-heading">
        <h2 id="trip-heading">Featured trip</h2>
        <article class="card">
          <h3>Lisbon team workshop</h3>
          <p>Destination: Lisbon, Portugal</p>
          <p>Duration: 3 days</p>
          <p class="trip-status">Status: Open for planning</p>
        </article>
      </section>

      <section id="request" aria-labelledby="request-heading">
        <h2 id="request-heading">Request information</h2>
        <form action="#" method="get" class="card request-form">
          <div class="field">
            <label for="traveler-name">Traveler name</label>
            <input
              id="traveler-name"
              name="travelerName"
              type="text"
              autocomplete="name"
              required
            />
          </div>

          <div class="field">
            <label for="destination">Destination</label>
            <select id="destination" name="destination" required>
              <option value="">Choose a destination</option>
              <option value="lisbon">Lisbon</option>
              <option value="porto">Porto</option>
              <option value="coimbra">Coimbra</option>
            </select>
          </div>

          <div class="field">
            <label for="departure-date">Departure date</label>
            <input
              id="departure-date"
              name="departureDate"
              type="date"
              required
            />
          </div>

          <button type="submit">Submit demo form</button>
          <p class="form-note">Demonstration only — no request is saved.</p>
        </form>
      </section>
    </main>

    <footer class="container">
      <p>Travel Desk · Web Development Foundations</p>
    </footer>
  </body>
</html>

Save index.html and let Live Server reload the page. You should now see the full page, even before styling it.

3.3 Why not use only <div> elements? ​

A <div> is useful when you need a generic container. But <nav>, <main>, <form>, and <button> tell the browser and assistive technology what the content is for.

Semantic HTML gives you helpful browser behavior without writing it yourself.

3.4 Labels, IDs, and names ​

Look at this pair:

html
<label for="traveler-name">Traveler name</label>
<input id="traveler-name" name="travelerName" type="text" required />

The attributes have different roles:

  • id="traveler-name" uniquely identifies the input on this page.
  • for="traveler-name" connects the label to that input.
  • name="travelerName" identifies the value during normal form submission.
  • required tells the browser that the field cannot be left empty for a normal submission.

Try it: click the text Traveler name on the page. The input should receive focus.

Now click Submit demo form with the required fields empty. The browser should block submission and prompt you to complete a field. The exact message depends on your browser and language.

This is a demonstration form

There is no backend or data storage. With method="get", a successfully validated form can put field values in the browser address bar as URL parameters, even though the page is running on Live Server. It does not save the request. Use only invented names and other practice data.

3.5 Quick HTML check ​

Discuss these with a partner:

  1. Why is the page title in <head> different from the visible <h1>?
  2. Which two attributes must match to connect a label and input?
  3. Does a required field guarantee that the information is correct?
  4. Why should a navigation link use <a href="..."> instead of a clickable paragraph?

Part 4 — Give the page a little CSS ​

HTML should make the page understandable before any styling is added. Now we will make it easier to read.

4.1 Add a short stylesheet ​

Open style.css and add:

css
* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: Arial, sans-serif;
  line-height: 1.5;
  color: #243247;
  background: #f5f7fa;
}

.container {
  width: min(100% - 2rem, 900px);
  margin-inline: auto;
}

.site-header {
  background: #17365d;
  color: white;
  padding: 1rem 0;
}

.site-header a {
  color: white;
  margin-right: 1rem;
}

main > section {
  margin-block: 2rem;
}

.card {
  background: white;
  border: 1px solid #d5dce5;
  border-radius: 0.75rem;
  padding: 1.25rem;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  margin-bottom: 1rem;
}

input,
select,
button {
  font: inherit;
  padding: 0.6rem;
}

input,
select {
  width: 100%;
  max-width: 100%;
}

button {
  cursor: pointer;
}

:focus-visible {
  outline: 3px solid #d48a00;
  outline-offset: 2px;
}

footer {
  padding-block: 1rem;
}

Save and watch Live Server reload the page.

4.2 Three CSS ideas to remember ​

Selector: the part before { identifies elements to style.

css
.card {
  padding: 1.25rem;
}

Box model: content has padding, a border, and margin around it.

text
margin → border → padding → content

Layout: Flexbox can arrange children in a row or column. Our form's .field class uses a column so a label appears above its input.

For today, you do not need to memorize all the properties. You need to recognize what a rule changes and know how to inspect it.

4.3 Test at a narrow width ​

Make the browser window narrow or use the device toolbar in DevTools. The page should remain readable, and the form controls should fit the available space.

Try changing one CSS value: the card padding, border radius, background color, or maximum container width. Save, watch the browser reload, and explain what happened.


Part 5 — Meet browser Developer Tools ​

Developer Tools (often called DevTools) let you inspect what the browser has built. They are useful even when you are not yet writing JavaScript.

Open your local page in Chrome or Edge. Press F12 or choose Inspect from the context menu.

5.1 Elements: inspect the DOM ​

  1. Right-click the Featured trip heading and choose Inspect.
  2. Find its <h2> element in the Elements panel.
  3. Look for the enclosing <section> element.
  4. Select the trip card. Locate the class="card" attribute.
  5. In the Styles pane, find the CSS rule for .card.
  6. Temporarily untick padding or change a color in DevTools.

Notice the page changes immediately. Did style.css in VS Code change? No.

DevTools lets you experiment with the current page, not automatically save source changes.

5.2 Change text in the live DOM ​

In the Elements panel, select the trip title and edit its text. You may see the new title right away.

Now refresh the page.

The original title returns because it still exists in your saved index.html.

Source versus live page

A change made in VS Code and saved persists through Live Server reloads. A temporary change in the Elements panel usually disappears when you refresh or the page reloads.

5.3 Console: ask the browser questions ​

Open the Console tab. Type these expressions one at a time and press Enter after each.

javascript
document.title

This shows the document's title from <head>.

javascript
document.querySelector("h1")

This looks for the first <h1> in the DOM. DevTools will show the element, or null if it cannot find one.

javascript
document.querySelector("h1").textContent

This reads the heading's text.

javascript
document.querySelectorAll("label").length

This counts the labels currently on the page.

Finally, try:

javascript
console.log("Hello from the browser Console!")

You have just executed a JavaScript statement inside the browser without adding a JavaScript file to the page.

We will learn JavaScript syntax properly from Lesson 2.

What if the Console shows a warning?

Read the exact message before changing anything. The Console may include browser messages unrelated to your work. If a command produces null, check that your selector matches an element on the page.

5.4 One small live DOM experiment ​

Type:

javascript
document.querySelector("h1").textContent = "Changed in the Console"

Look at the visible page. The main heading changes!

Now refresh.

The original heading returns. You changed the browser's live DOM, not the HTML file.

This is an early preview of what JavaScript will allow us to do later.

5.5 Network: what loaded? ​

Open the Network panel, make sure recording is on, and refresh the browser.

Look for:

  • index.html (the HTML document);
  • style.css (the stylesheet).

These files are now being requested using HTTP, because Live Server is serving them locally. When they load correctly, you will usually see a successful status such as 200. You may also see a Live Server reload connection or additional browser resources; that is normal.

Try clicking the document request and finding its Request URL, Status Code, and Response details.

Why are we doing this now?

Later lessons will make API requests with JavaScript. The same Network panel will help you find their URLs, status codes, and responses. Today we are only observing our HTML and CSS.


Part 6 — Two small debugging experiments ​

The first question during debugging is not "Which random line should I change?" It is "What evidence can I observe?"

6.1 A broken label ​

In VS Code, change:

html
<label for="departure-date">Departure date</label>

to:

html
<label for="depart-date">Departure date</label>

Leave the input's id="departure-date" unchanged.

Save and let Live Server reload. Click the label on the page.

It no longer targets the intended input.

In Elements, compare the label's for with the input's id. Then correct the label in VS Code, save, and test again after the reload.

What should you say when explaining the fix?

"The label's for must match the input's id. The values differed, so I corrected the label and retested it."

6.2 A missing stylesheet ​

In index.html, temporarily change:

html
<link rel="stylesheet" href="./style.css" />

to:

html
<link rel="stylesheet" href="./missing.css" />

Save and let Live Server reload. What changed visually?

Open Network and look for the request to missing.css. It should fail (commonly with HTTP 404 Not Found), because that file does not exist. The layout has lost its styling because the browser could not load the stylesheet.

Restore ./style.css, save, and let Live Server reload.

A useful debugging habit ​

text
1. Describe what is wrong.
2. Observe the page and DevTools.
3. Form a likely explanation.
4. Change one thing in the source.
5. Save, let Live Server reload, and retest.

Part 7 — Independent classroom checkpoint ​

Complete these changes without copying new code from the teacher:

  1. Change the browser tab title.
  2. Change the featured-trip destination.
  3. Add a fourth destination option to the form.
  4. Change one CSS value.
  5. Use Console to count the labels on the page.
  6. Explain why editing a heading in Elements is not the same as editing it in VS Code.

End-of-lesson checklist ​

Before moving to independent practice, confirm that you can:

  • [ ] Install Live Server in VS Code and open index.html using Open with Live Server.
  • [ ] Explain why the browser address starts with http://localhost or http://127.0.0.1.
  • [ ] Tell someone what HTML, CSS, and JavaScript are responsible for.
  • [ ] Identify a <header>, <main>, <section>, <form>, and <label>.
  • [ ] Explain why for and id must match on a labeled field.
  • [ ] Make and observe a small CSS change.
  • [ ] Find an element and its CSS rules in Elements.
  • [ ] Find index.html and style.css in Network and identify a successful HTTP status.
  • [ ] Use Console to read document.title and the page's heading.
  • [ ] Explain what the DOM is in your own words.
  • [ ] Correct a broken label and a broken stylesheet link.

Knowledge check ​

1. What is the difference between HTML, CSS, and JavaScript?

HTML gives content structure and meaning; CSS handles appearance and layout; JavaScript adds logic and behavior.

2. What is the DOM?

The browser's object representation of the current document. It can be changed without editing the original HTML file.

3. Why are we using Live Server?

It serves our plain HTML and CSS over a local HTTP address and reloads the browser after we save changes. We do not need Vite, npm, or a backend.

4. Why does a temporary edit in Elements disappear after refresh?

The edit changed the live DOM, not the saved HTML file.

5. Why can required work without our own JavaScript?

Browsers already implement native form validation for standard HTML controls.

Next step ​

In your independent practice, you will build your own Northstar Travel Request page. The companion has examples you can adapt, but you should make the main decisions yourself.

In Lesson 2, we will begin writing JavaScript more seriously: values, variables, operators, and expressions.

Helpful references ​