How HTML works
What markup actually is: elements, attributes and the skeleton every document shares — and what the browser does with it.
HTML describes what content is, not how it should look. A heading is a heading because you wrapped it in a heading element — the size and weight it happens to have in one browser are a side effect, not the point. That separation is why a screen reader, a search engine and a browser can all read the same document and each take what it needs.
A page is built out of elements. An element is an opening tag, some content, and a closing tag. Attributes go inside the opening tag and describe the element further.
It is worth knowing what the browser does with the file, because it explains most of the mistakes in this chapter. The bytes arrive, the declared encoding turns them into characters, and a parser scans those characters for tags. Each tag, attribute and run of text becomes a token, and the tokens are assembled into a tree in the order they appear. A page with a mistake is not rejected: the parser repairs it by rules of its own, and the tree it builds may not be the one you meant.
An element, piece by piece
<p>— the opening tag: the name of the element, in angle brackets.Hello— the content: text, or other elements.</p>— the closing tag: the same name with a slash. Everything between the two tags is inside the element.<p class="lead">— an attribute: a name, an=, and a value. Attributes only ever live in the opening tag.<br>— an empty element: it holds nothing, so it has no closing tag.<img>,<input>and<hr>are the other common ones.
The example below is a complete page. Run it, then change it — the preview updates as you type, and Run restarts it from the top.
Your first page
Change the heading text to your own name, then add a second paragraph under it.
1 left to do
- The page has a heading
- There are at least two paragraphs
A paragraph is <p>…</p>, and it sits inside <body> like the heading does.
The skeleton every document shares
The lines before your content are not decoration. <!DOCTYPE html> tells the browser to use the modern rules rather than its quirks. <html> is the outermost element. Inside it, <head> holds information about the page — the title shown in a tab, the character encoding, the description a search engine reads — and <body> holds everything that is actually displayed.
Keep that shape even when a page is short. A document that skips it still renders, because browsers are forgiving, but the forgiveness is not a feature you want to rely on: the page then depends on guesses.
The same skeleton, once more
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Shown in the browser tab</title>
</head>
<body>
<h1>Shown on the page</h1>
</body>
</html>Elements nest: a parent holds children. The browser turns that nesting into a tree — the DOM — and everything after this chapter is really about choosing the right branches.
Attributes describe an element
Give the link a real destination with href, and add a title that explains where it goes.
2 left to do
- The link has an href
- The link has a title
Both live in the opening tag: <a href="…" title="…">.
Attributes have rules too
An attribute value can go in double or single quotes, and a value that contains a space has to be quoted. class="card wide" is one attribute with two class names; class=card wide is an attribute with a broken value and the word wide sitting loose in the tag. Quote every value and the question never comes up.
Some attributes are switches: required, controls, disabled and checked are present or absent, and writing required="required" changes nothing. Others need a value before they mean anything. The name is lowercase by convention, and an attribute written after the closing > is no longer an attribute — it is text the reader can see.
How the browser repairs a page
The repairs are predictable once you have seen them. A <div> that is never closed stays open until the end of its parent, so everything written after it becomes a child rather than a sibling. A closing tag that arrives in the wrong order is resolved by closing what is still open: in <p><strong>Text</p></strong>, the </p> ends the paragraph and the emphasis inside it, and the extra </strong> has nothing left to close. The page still draws, which is why the mistake survives until something else depends on the structure.
Text is not markup, which is the other half of the rule. A < that does not begin a valid tag is treated as text, and an & begins a character reference. That is why a literal less-than sign in a sentence is written <; without it the parser is entitled to read the next word as a tag name, and the sentence disappears into an element that was never there.
Three mistakes account for most broken pages: a tag left open, so the rest of the document nests inside it; an attribute written after the > instead of before it, where it becomes visible text; and the same id used twice, which makes every fragment link and label point at the first one. A validator catches the first and the third; the second is visible the moment you look at the page.
Try these next
- Add a
langattribute to<html>and atitleto the page, then view the source to see where each one sits. - Give two elements the same
idand watch which one a#namelink reaches. - Write a paragraph with an unclosed
<strong>and see how far the emphasis reaches.
Tag names are case-insensitive — <H1> and <h1> are the same element — but writing them in lowercase is the convention you will see everywhere, including in this course.
Check what you learned
One question at a time. A wrong answer explains itself — take another go.
Part 1 of 6
In <a href="/about">About</a>, which part is the attribute?
