Chapter 5 · The web page
A web page
Step 1 of 22 · Concept
Your first web page
By the end of this lesson you can:
- write a web page in HTML,
- style it with CSS,
- change it from JavaScript.
It is the same JavaScript as in lessons 1–20. Now it runs in a web page, and Run shows that page in the Page tab.
Step 2 of 22 · Demo
Run a page
Press Run. The Page tab shows the page: a heading and a paragraph, not lines of output.
Then change the text between <h1> and </h1> and run it again.
Step 3 of 22 · Concept
HTML marks up text with elements
<h1>Shopping</h1> is an element: a start tag, the content, then an end tag with a /. The tag's name says what
the content is: a heading.
An element can hold other elements. Every page has the same frame:
<!DOCTYPE html>says it is today's HTML.<html>holds the whole page.<head>is about the page: its<title>, and<meta charset="utf-8">, which has no end tag.<body>holds what shows.
Step 4 of 22 · Concept
A few elements do most of the work
| element | is |
|---|---|
h1 | a heading |
p | a paragraph |
ul and li | a list, and each item in it |
button | a button to press |
div | a box with no meaning of its own |
span | a piece of text with no meaning of its own |
An attribute in the start tag adds a detail. <h1 id="title"> names this one element: an id is used once in a
page. <li class="done"> puts the item in the group done, which many elements can share.
Step 5 of 22 · Quiz
Which one nests correctly?
A span inside a p. Which line nests correctly?
Step 6 of 22 · Exercise
Your turn: a shopping list
The page has only its frame. In its body, write a heading Shopping and a list of three items: Milk, Bread,
Eggs. The Page tab must show:
Shopping
• Milk
• Bread
• Eggs
Everything that shows goes between <body> and </body>. Each li goes inside the ul, so </ul> comes after the last </li>.
An h1 with its start and end tag, then a ul that holds three li elements, one per item.
<ul>
<li>Milk</li>
Step 7 of 22 · Concept
CSS says how it looks
A CSS rule is a selector, then property: value; pairs in braces. The selector says which elements it styles:
| selector | styles |
|---|---|
p | every p |
.done | every element with class="done" |
#title | the element with id="title" |
The rules go in a file of their own, style.css. The page's head names it:
<link rel="stylesheet" href="style.css">.
Step 8 of 22 · Concept
Six properties to start with
| property | sets | for example |
|---|---|---|
color | the text's colour | gray, red |
background-color | the colour behind it | lightyellow |
font-size | the text's size | 24px |
margin | the space outside the border | 16px |
padding | the space inside the border | 8px |
border | the line around it | 2px solid black |
px is a CSS pixel, about one dot of an ordinary screen. A border names its width, its style (solid, dashed) and its colour.
Step 9 of 22 · Quiz
Which items turn grey?
The page has this list, and style.css has one rule. Which items turn grey?
<ul>
<li class="done">Milk</li>
<li>Bread</li>
<li class="done">Eggs</li>
</ul>
.done { color: gray; }
<ul>
<li class="done">Milk</li>
<li>Bread</li>
<li class="done">Eggs</li>
</ul>.done { color: gray; }Step 10 of 22 · Demo
See the style
Run it: the heading has a border, with padding inside it, and the done items are grey. Then change gray to red
in style.css and run it again.
Step 11 of 22 · Try it
Try it: hide what is done
Add one rule to style.css so that the done items do not show at all. Only Bread stays in the list.
A rule whose selector is .done, with display: none; in its braces.
Step 12 of 22 · Concept
The page becomes objects
The browser reads index.html and builds an object for each element, in a tree: the DOM. body holds h1 and
ul, and ul holds three li. The objects live on the heap, as lesson 10's arrays do.
<script type="module" src="script.js"></script>, at the end of the body, runs script.js as a module
(lesson 8). It runs once the whole page is read, so every element is there for it.
Step 13 of 22 · Concept
Find an element, read its text
const title = document.querySelector("#title");
console.log(title.textContent);
title.textContent = "My list";
documentis the page.querySelectorgives the first element its CSS selector matches, ornullwhen none does. Thentitle.textContentstops the script with aTypeError.document.querySelectorAll("li")gives all of them, for afor...of.textContentis an element's text;=changes it, and the page shows the new text.
The page's console.log lines appear in Output.
Step 14 of 22 · Quiz
What does the script log?
The page has <h1 id="title">Shopping</h1> and a list of three li. Type the missing line.
const title = document.querySelector("#title");
console.log(title.textContent);
title.textContent = "My list";
console.log(title.textContent);
console.log(document.querySelectorAll("li").length);
Step 15 of 22 · Demo
See it run
Run it and compare Output with your answer. The heading in the Page tab now reads My list.
Step 16 of 22 · Demo
A class switches a style on and off
classList holds an element's classes. add("done") puts the class on, remove("done") takes it off, and
toggle("done") flips it. The look stays in style.css: the script only names the class.
items[0] is the first li, as in an array. Run it: only Bread is grey.
Step 17 of 22 · Concept
Build elements from an array
const item = document.createElement("li");
item.textContent = "Tea";
list.append(item);
document.createElement("li")makes a newliobject, not yet on the page.list.append(item)makes it the list's last child, and the page shows it.item.remove()takes an element off the page.
For an array, a for...of makes one li per item.
Step 18 of 22 · Demo
A list from an array
The script removes the Nothing yet item, then adds one li per task. Run it: <b>Tea</b> shows as text.
Then change item.textContent to item.innerHTML and run it again: the tags turn into an element, and Tea is bold.
Step 19 of 22 · Exercise
Your turn: a to-do list
Show the array todos as a list:
- Find the
ulwhoseidistodos. - Add one
liper task, its text the task's title. - Give the done ones the class
done, so they are grey.
A new li shows only once it is in the list. Make it, give it its text, then append it, all inside the loop.
Find the list once, before the loop: document.querySelector("#todos"). In a for...of over todos, document.createElement("li"), its textContent, an if on done with classList.add, then append.
const item = document.createElement("li");
Step 20 of 22 · Check yourself
Check yourself: a scoreboard
Show each player as an item Ada: 90, and change the heading to say how many players there are. No plan this
time. The Page tab must show:
3 players
• Ada: 90
• Alan: 85
• Grace: 95
Two parts: the heading's text from the array's length, then the to-do list's loop, with a template literal for each item's text.
Step 21 of 22 · Challenge · optional
Challenge: the total price
Optional.
Each li carries its price in an attribute, data-price="2.50". Add up the three prices and show the total in
#total, with two decimals:
Total: 4.50
An attribute whose name starts with data- is yours to name. item.dataset.price reads data-price, as text: "2.50".
Text added to a number joins: 0 + "2.50" is "02.50". Wrap each price in Number(...), add it to a sum in a for...of over querySelectorAll("li"), then toFixed(2).
sum += Number(item.dataset.price);
Step 22 of 22 · Recap
Recap
- A page is elements in elements:
htmlholds itsheadand itsbody. - A CSS rule such as
.done { color: gray; }styles what its selector matches. - The browser makes the page a tree of objects, the DOM;
script.jsruns once the page is read. querySelector,textContentandclassListfind and change elements;createElementandappendadd them.innerHTMLturns text into elements: never give it text a user typed.
Next: lesson 22 makes the page answer clicks and forms.
Review
3 questions from this lesson, in a new order each time. Answer from memory: 2 of 3 right on the first try passes. On a day after you finish the lesson, a pass earns 15 XP.
The review needs JavaScript.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Shopping</title>
</head>
<body>
<h1>Shopping</h1>
<p>Three things to buy.</p>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Shopping</title>
</head>
<body>
</body>
</html>
#title {
border: 2px solid black;
padding: 8px;
}
.done {
color: gray;
}
#title {
border: 2px solid black;
padding: 8px;
}
const title = document.querySelector("#title");
console.log(title.textContent);
title.textContent = "My list";
console.log(title.textContent);
console.log(document.querySelectorAll("li").length);
const items = document.querySelectorAll("li");
items[0].classList.remove("done");
items[1].classList.add("done");
items[2].classList.toggle("done");
const tasks = [
{ title: "Buy milk", done: true },
{ title: "<b>Tea</b>", done: false },
{ title: "Call Bo", done: false },
];
const list = document.querySelector("#list");
document.querySelector("#empty").remove();
for (const task of tasks) {
const item = document.createElement("li");
item.textContent = task.title;
if (task.done) {
item.classList.add("done");
}
list.append(item);
}
console.log(`Added ${tasks.length} items`);
const todos = [
{ title: "Water plants", done: false },
{ title: "Buy milk", done: true },
{ title: "Call Bo", done: false },
];
// 1. find the ul whose id is todos
// 2. one li per task, its text the title
// 3. the class done on the done ones
const players = [
{ name: "Ada", score: 90 },
{ name: "Alan", score: 85 },
{ name: "Grace", score: 95 },
];
const total = document.querySelector("#total");
// add up the prices, then show the total