Skip to content
wannacode

The HTML document

In short: An HTML document is text with tags and attributes from which the browser builds a tree of elements; semantic elements such as header, nav, main and footer say what each part is.

Problem

The price is a link

A colleague made the page of a product. You open it and the price is blue and underlined, and a click on "Add to cart" takes you to other breads. The code has no link around the price.

HTML, CSS, JS
index.html

The browser shows no error and the console is empty. Press "Add to cart": the console says that this is a link to /bread. The mistake is on line 9: the <a> is opened but never closed. The browser does not show the text line by line. It first builds something else from it, and that something is why the price is a link.

The idea

Elements, tags, attributes

HTML is text that says what is on the page. Every piece is an element: a heading, a paragraph, a link, a button. An element starts with an opening tag and ends with a closing one:

<a href="/cart">Cart</a>
  • <a …> is the opening tag, and </a> is the closing one: the same name with a /.
  • href="/cart" is an attribute: a name and a value in the opening tag. It says something about the element: here, where the link goes.
  • "Cart" is the content: the text between the two tags.

Elements sit inside each other. A paragraph <p> can hold a link, and <body> holds everything you see. Some elements have no content and so no closing tag: <meta>, <img>, <input>, <br>.

The whole document always has the same frame:

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Dobrudzha bread</title>
</head>
<body>
…
</body>
</html>

<!doctype html> says that this is modern HTML. lang="en" gives the language: a screen reader picks its voice by it, and the browser breaks words by it. <head> holds information about the page: the encoding and the title in the browser tab. <body> holds what you see.

The idea

From text to a tree

The browser does not draw the text. It reads it with a parser and builds a tree: every element is a node, and the elements inside it are its children. Every element has exactly one parent. This tree is called the DOM (Document Object Model). CSS and JavaScript work with it, not with the text.

The parser keeps track of which elements are open right now. An opening tag makes a new node, a child of the last open element. A closing tag closes the element, and the parser goes back to the parent.

If a closing tag is missing, the parser does not stop. HTML has a rule for every mistake, and the browser decides by itself where to close. Sometimes it decides differently from what you had in mind.

See it

See the tree being built

The code is the problem from the start, made short. Watch which elements are open on the right.

<body>
<h1>Bread</h1>
<p>See the <a href="/bread">other breads</p>
<p>Price: €1.80</p>
<button>Add</button>
</body>
Step by step, in words
  1. The parser reads the code from the top. <body> opens an element: here it is the root of the tree. On the right are the elements that are open right now.
  2. <h1> becomes a child of the open element, <body>. </h1> closes it on the same line, and the parser goes back to <body>.
  3. <p> is a child of <body>, and <a> is a child of <p>. Now three elements are open: body, p, a.
  4. There is no </a>. </p> closes the paragraph, and <a> cannot stay outside it, so it is closed too. But the parser keeps it in mind: the link was never closed in the code.
  5. Before the next content the parser opens the kept <a> again, now as a child of <body>. This link is not in the code. The new <p> goes inside it.
  6. The button goes inside the link too.
  7. The path from the button up: button, a, body. The price and the button are inside a link, and a click on them leads to /bread. The fix is one </a> on line 3.

The second <a> is not in the code, but it is in the tree. The browser shows the tree, not the text. So when a page looks strange, you look at the tree: in the browser this is the Elements panel of the developer tools (F12). The second <a> is there, and the source (View Source) does not have it.

Try it

Fix the link

Fix the code so that the page has exactly one link: "other breads". Press "Check": the check counts the links on the page.

HTML, CSS, JS
index.html

Try it

Find the bug

Why is "Delivery in 2 working days" bold?

Pick the line with the bug.

Try it

Fill in

Which attribute says where the link goes?

<nav>
  <a ="/cart">Cart</a>
</nav>

The idea

Elements with meaning

A page can be made only of <div> elements. Then the browser knows that there are boxes, but not what each one is. A person sees the menu by its place and its look. A screen reader, a search engine and the keyboard see only the tree.

So HTML has semantic elements: elements whose name says what the content is.

  • <header>: the top of the page: the logo and the menu.
  • <nav>: the navigation, the group of links to the other pages.
  • <main>: the main content. One per page.
  • <article>: something whole that makes sense on its own: a product, an order, a post.
  • <footer>: the bottom of the page: delivery, contacts, terms.
  • <h1> … <h6>: the headings. <h1> is the heading of the page.

They look like a <div>. The difference is that a screen reader announces "navigation" and "main", and a keyboard user jumps to them with one key. <div> and <span> stay for boxes with no meaning: a group that CSS has to lay out.

See it

The page with meaning

The same product with semantic elements. The second file has a little CSS so that the parts are visible. The next module is about it.

HTML, CSS, JS

The check of the example finds the parts by role: <header> is "banner", <nav> is "navigation", <main> is "main", <footer> is "contentinfo". A screen reader sees them the same way.

Try it

Give it meaning

The page is made only of <div> elements. Replace them with semantic elements: the top, the menu, the main content, the product and the bottom. The name of the product is the heading of the page.

HTML, CSS, JS
index.html
More precisely, if you are curious

The parser and mistakes. The rules for mistakes are part of the standard (the HTML Living Standard), so all browsers build the same tree from the same broken HTML. The parser keeps unclosed <a>, <strong>, <em>, <b> and <i> in a list (the list of active formatting elements) and opens them again. That is why such a mistake "spills" down the page.

Closed by itself. Some tags close others without a mistake: <p> closes an open <p>, and <li> closes an open <li>. So <li>Bread<li>Milk is two list items. We write the closing tags because then the code says the same as the tree.

Attributes. The names of tags and attributes do not depend on upper and lower case (<A HREF> is <a href>), but we write lower case. Some attributes have no value: <input required>. The quotes around a value can be left out, but they are safer.

<section> and <aside>. <section> is a part with a heading, a piece of something bigger. <aside> is content to the side of the main one: related products, an ad.

Exercise

My order

Make the page of order 1042 from scratch. At the top: a link "The shop" and a menu with two links: "My orders" and "Cart". The main content: the heading "Order 1042", the status "shipped" and two products, each with its name as a second-level heading and the quantity with the price under it (bread: 2 × €1.80, milk: 1 × €2.40), then "Total: €6.00". At the bottom: "Returns within 14 days of delivery".

HTML, CSS, JS
index.html

Test

Test yourself

1. The browser gets HTML with a tag that is not closed. What does it do?
2. In <a href="/cart">Cart</a>, which part is the attribute?
3. Why put the menu in <nav> and not in <div class="menu">?
4. How many <main> elements does a page have?

Made by Ivo Gergov as part of Evo Tech's campaign for accessible programming education ·