Skip to content

Lesson 1 — Companion reference ​

This is your reference for Lesson 1 and its independent practice. You do not need to memorize every tag or property. Look up the part you need, try the example, and return to your own work.

Today we use plain HTML, CSS, VS Code, Live Server, and a browser. The Live Server extension serves your saved files locally and reloads the page when you save. No Vite, npm, or generated application is needed.

Find what you need ​

I want to…Read…
Understand HTML, CSS, JavaScript, and the DOMThe web page mental model
Open my page with Live Server and make changesWorking with local files
Choose the right HTML elementHTML essentials
Label and validate a formForms and accessibility
Make a page readable at different sizesCSS essentials
Inspect a page and run Console expressionsDevTools reference
Fix a problemTroubleshooting

1. The web page mental model ​

Think of your web page in three layers:

text
Saved files on disk
├── index.html → content and meaning
└── style.css  → appearance
             │
             ▼
        Live Server
       (local HTTP)
             │
             ▼
           Browser
             │
             ├── Reads HTML
             ├── Builds the DOM
             ├── Applies CSS
             └── Renders what users see

JavaScript will eventually be another layer. It can read and change the DOM, respond to actions, and work with data. You will learn to write it properly in the next lessons.

Three things that sound similar ​

ThingWhat it isHow to inspect it
HTML sourceThe file you savedOpen index.html in VS Code
DOMThe browser's current object representation of the documentUse the Elements panel
Rendered pageThe visual resultLook at the browser window

If you edit a heading only in Elements, the browser may immediately show your change. But your file has not changed; refreshing loads the original text again.

Short version

Source is saved. DOM is live. CSS affects how the DOM looks.


2. Working with local files ​

2.1 Folder layout ​

For today's work, keep things simple:

text
my-page/
├── index.html
└── style.css

The index.html document references the stylesheet using a relative path:

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

./style.css means "the file named style.css in the same folder as this HTML file."

2.2 Install and use Live Server ​

Install once:

  1. In VS Code, open Extensions.
  2. Search for Live Server.
  3. Select the extension published by Ritwick Dey (ritwickdey.LiveServer).
  4. Click Install.

For each HTML exercise:

  1. Open your exercise folder in VS Code (File → Open Folder).
  2. Open index.html in the Explorer.
  3. Right-click the file and select Open with Live Server. You can also use Go Live in the status bar.
  4. The browser opens at an address like http://127.0.0.1:5500/index.html. The port may differ.
  5. Edit index.html or style.css, then save the file. Live Server should automatically reload the page.
  6. To stop the server, select the Live Server status control in VS Code or use the command Live Server: Stop Live Server.

If reloading does not happen, refresh manually and check that you are editing the same folder and file Live Server is serving.

2.3 file:// versus http:// ​

file://http://localhost / http://127.0.0.1
Opens a file directly from diskLoads a file through a server running on your own computer
Does not make a normal HTTP request for the documentUses ordinary HTTP requests and response status codes
Some browser features behave differently or are restrictedCloser to how browser-hosted web applications work
Not our standard preview workflowOur Lesson 1 preview workflow

The local server is not an online deployment and does not store form submissions. You will learn HTTP in more depth later.

Demo forms do not save requests

Our example form uses method="get". After valid submission, the browser may place the entered values in the page URL, but no backend receives or stores a travel request. Always use invented practice information.


3. HTML essentials ​

3.1 A minimal document ​

html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>My Page</title>
    <link rel="stylesheet" href="./style.css" />
  </head>
  <body>
    <header><p>My Site</p></header>
    <main>
      <h1>Welcome</h1>
      <p>Hello from my first page.</p>
    </main>
    <footer>Training example</footer>
  </body>
</html>

The important lines are:

  • <!doctype html>: tells the browser to use modern standards-mode processing.
  • lang="en": declares the document language.
  • <meta charset="UTF-8">: identifies the character encoding.
  • <meta name="viewport" ...>: helps mobile browsers lay out the page as intended.
  • <title>: appears in the browser tab, not in the page body.
  • <h1>: the visible page heading.
  • <link ... href="./style.css">: loads the stylesheet from the same folder.

3.2 Which element should I use? ​

You want to…A good choice
Show introductory site content<header>
Group navigation links<nav>
Identify the primary page content<main>
Group related content under a heading<section>
Show one self-contained card or news item<article>
Show a list of items<ul> with <li>
Show a table of actual data<table>
Move to another location/page<a href="...">
Offer a user action<button>
Receive input<form> and its controls

<div> is still useful for generic layout grouping. It simply does not describe the purpose of its contents as clearly as the semantic elements do.

3.3 Heading hierarchy ​

A clear page can use:

text
h1  Travel Requests
    h2  Available journeys
        h3  Porto workshop
        h3  Lisbon meetings
    h2  Request a trip

Heading levels communicate a structure. Do not choose <h3> only because you like its default font size. Choose the level that matches the content, then change its appearance with CSS if needed.

html
<a href="#request">Go to the request form</a>

<section id="request">
  <h2>Request a trip</h2>
</section>

The part after # refers to an element's id on the page. That ID must exist and should be unique.


4. Forms and accessibility ​

4.1 A labeled input ​

html
<label for="work-email">Work email</label>
<input
  id="work-email"
  name="workEmail"
  type="email"
  autocomplete="email"
  required
/>

Each attribute serves a different purpose:

AttributePurpose
idUniquely identifies the element in the document
for on <label>Connects label and input through matching IDs
nameNames the field value for normal form submission
typeChooses an appropriate browser control and some built-in validation
requiredTells the browser not to accept an empty value for normal submission
autocompleteHelps browsers suggest appropriate saved values

Try it: click the visible label text. The matching input should receive focus. If nothing happens, compare for and id letter by letter.

4.2 Common form controls ​

FieldExampleWhat the browser provides
Name<input type="text">Text entry
Email<input type="email">Some email-format checking
Date<input type="date">Date entry; UI varies by browser/system
Number<input type="number" min="1" step="1">Numeric entry and range/step validation
Destination<select>Choice from options
Notes<textarea>Multi-line text entry

For a required destination select, the first option should have an empty value:

html
<label for="destination">Destination</label>
<select id="destination" name="destination" required>
  <option value="">Choose a destination</option>
  <option value="porto">Porto</option>
  <option value="lisbon">Lisbon</option>
</select>

4.3 Native validation: useful but limited ​

These attributes can provide checks without your writing JavaScript:

html
<input type="email" required />
<input type="number" min="1" step="1" required />

But remember:

  • Email validation checks the shape of a value; it does not prove the address exists.
  • required checks that an input has a value; it does not prove the value is true.
  • HTML checks help users, but do not replace server-side validation in real applications.

4.4 What happens when we submit a demo form? ​

A demonstration form may use:

html
<form action="#" method="get">
  <!-- labeled controls -->
  <button type="submit">Submit demo form</button>
</form>

After all required controls are valid, the browser may navigate and put the submitted values in the URL as query parameters. Live Server will continue to serve the page, but no information is saved because we have not built a service to receive and store it.

Use invented names and emails when experimenting. GET form values may become visible in the URL and browser history.

4.5 Keyboard access and visible focus ​

Use Tab to move forward between interactive elements and Shift+Tab to go backward. Verify that the focused element has a visible outline or other indicator.

You can improve focus visibility with:

css
:focus-visible {
  outline: 3px solid darkorange;
  outline-offset: 2px;
}

Do not remove the browser's default outline unless you provide an accessible replacement.


5. CSS essentials ​

5.1 Selectors ​

css
p {                    /* every paragraph */
  line-height: 1.5;
}

.card {                /* class="card" */
  padding: 1rem;
}

#request {             /* id="request" */
  margin-top: 2rem;
}

.card h3 {             /* h3 inside a card */
  margin-top: 0;
}

A class can be reused across many elements. An ID should identify one element on the page.

5.2 Spacing and the box model ​

text
margin
└── border
    └── padding
        └── content
  • padding adds space inside a box's border.
  • border surrounds the padded content.
  • margin adds space outside the border.

A helpful rule is:

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

It means an element's declared width includes its padding and border, but not its margins.

5.3 Flexible widths ​

Avoid designing only for one screen size.

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

The container can become narrow on smaller screens but does not grow indefinitely on large screens.

5.4 A little Flexbox ​

css
.field {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

In this example, the label and input stack vertically.

You can also arrange cards in a wrapping row:

css
.cards {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

.cards > * {
  flex: 1 1 15rem;
}

5.5 A media query, if you need it ​

css
@media (min-width: 700px) {
  .request-form {
    max-width: 38rem;
  }
}

A media query changes styles when its condition is met. You do not need a media query for every responsive layout; flexible widths and wrapping often solve the problem on their own.

5.6 Common layout check ​

At a narrow screen width, check that:

  • text is not clipped;
  • you can still read each label and input;
  • buttons can be reached and used;
  • the entire page does not scroll horizontally;
  • focus remains visible.

6. DevTools reference ​

6.1 Elements ​

Use Elements when you want to know:

  • What HTML/DOM element am I looking at?
  • Which class or ID does it have?
  • Which CSS rules apply?
  • Is the label's for the same as the input's id?

Steps: right-click the visible part → Inspect → select the element → examine Styles.

Changes made in Elements are normally temporary. Your saved files remain unchanged.

6.2 Console ​

The Console lets you inspect the current page and, later, debug JavaScript.

Type these commands one at a time:

javascript
document.title
javascript
document.querySelector("h1")
javascript
document.querySelector("h1").textContent
javascript
document.querySelectorAll("input").length
javascript
console.log("The Console is working")

querySelector returns the first matching element or null. If the element exists, .textContent reads its text. querySelectorAll(...).length counts matching elements.

You can also change the live page:

javascript
document.querySelector("h1").textContent = "Temporary heading"

Refresh and the original heading should return, because the source file did not change.

When a Console expression fails

Check quotation marks, parentheses, and the CSS selector. Also check whether the element exists. If document.querySelector(...) returns null, reading .textContent from it will cause an error.

6.3 Network ​

The Network panel helps investigate loaded resources and, in later lessons, HTTP/API requests.

Today Live Server supplies files over HTTP. Reload with the Network panel open, then find index.html and style.css. Successful requests will usually have status 200. A stylesheet link to a nonexistent path will typically have status 404. The browser may also show other requests used by Live Server itself.

When something does not load, check the path referenced in your HTML:

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

Then confirm that the file is really named style.css and is next to index.html.

6.4 Device toolbar ​

Use the device toolbar in DevTools (or resize the window) to test a narrow viewport. A useful comparison is approximately 375 CSS pixels wide versus a desktop width.

Check the page, not just the screenshot: can you still read and operate everything?


7. Troubleshooting ​

ProblemLikely reasonFirst action
Browser shows old textFile not saved, or a different file/folder is being servedSave the correct file; check the Live Server URL; refresh manually if needed
Browser displays HTML tags as plain textFile may have been saved incorrectlyConfirm .html extension and open index.html with Live Server
CSS does not appearWrong link path or filenameConfirm href="./style.css" and folder location
Clicking a label does not focus the fieldfor and id do not matchCompare exact attribute values
In-page navigation does not move to a sectionhref="#..." does not match a section IDCheck both values
A field is not submittedIt may lack a nameInspect the control's attributes
Required selection accepts a placeholderPlaceholder may have a nonempty valueSet the initial option to value=""
Page overflows on mobileFixed widths or unwrapped contentInspect CSS widths in Elements
Console expression returns nullThe selector found no matching elementInspect the actual tag/class/ID
Console expression produces an errorSyntax mistake or accessing a missing elementRead the message; check characters and selection
Valid form changes the URL after submitGET form fields become URL query parametersExpected for the demo; nothing is stored; use sample data
Network shows no HTTP requests for your pageOpened via file:// rather than Live ServerRight-click index.html → Open with Live Server
Go Live is missingExtension not installed/enabled or no folder openInstall Live Server (Ritwick Dey), open the folder, and reload VS Code if needed
A different page opensLive Server serves a different folder or fileOpen the correct project folder; right-click its index.html
Stylesheet request is 404Wrong filename or relative pathCheck href="./style.css" and the file location

A repeatable debugging approach ​

text
Observe → Explain → Change one thing → Save → Check reload → Retest

That approach is more reliable than changing multiple unrelated lines and hoping for the best.


8. Self-check ​

Why is <main> better than a generic <div> for the main content?

It describes the purpose of that region and improves the document's semantic structure.

What is the difference between class and id?

A class groups elements, usually for reuse and styling. An ID uniquely identifies one element within the document.

What is the difference between id and name on a form control?

The ID identifies the control in the document and can connect it to a label. The name identifies the value in form submission.

Why can a form reject an empty required field with no JavaScript file?

The browser implements built-in HTML constraint validation.

How can the page change in DevTools without index.html changing?

DevTools can edit the live DOM or applied styles in memory. Those changes are not automatically written to the original source files.

Can we inspect HTTP status codes using Live Server?

Yes. The browser requests HTML and CSS using HTTP from your local computer. Successful requests commonly have status 200; missing files commonly have status 404.


9. Small examples for the practice ​

Use these as references, not as a complete solution.

A journey card ​

html
<article class="card">
  <h3>Example trip</h3>
  <p>Duration: 2 days</p>
</article>

A labeled field ​

html
<div class="field">
  <label for="department">Department</label>
  <input id="department" name="department" type="text" required />
</div>

Cards that wrap ​

css
.card-list {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

An email field ​

html
<label for="email">Email</label>
<input id="email" name="email" type="email" required />

10. Useful documentation ​

Ready to work independently? Open the Lesson 1 practice.