HTML Document Structure
Table of Contents
- The Skeleton of Every Page
- The Doctype
- The html Element and the lang Attribute
- The head: Information About the Page
- The body: What People See
- Elements, Tags, and Attributes
- Nesting and Indentation
- Void Elements and Comments
- Validating Your HTML
- Try It Yourself
1. The Skeleton of Every Page
Every HTML page, from a tiny test file to a huge website, has the same skeleton. It's the file you typed in the last chapter:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Dara Sok</title>
</head>
<body>
<h1>Hello, I'm Dara</h1>
<p>I'm learning to build websites.</p>
</body>
</html>
It has three layers: a doctype declaration, then the <html>
element that contains everything, which in turn holds a <head>
(information about the page) and a <body> (the page itself). Let's
go through them in order.
2. The Doctype
<!doctype html>
This first line tells the browser: "this is a modern HTML document." Without it, browsers switch to quirks mode, a compatibility mode that imitates browsers from the 1990s and makes layouts behave in strange ways. It isn't an element and it isn't case-sensitive, but the lowercase form above is the standard. Always include it.
3. The html Element and the lang Attribute
<html lang="en">
<html> is the root element: every other element lives inside it.
The lang attribute declares the page's language, and it matters more
than it looks:
- Screen readers choose the right pronunciation. Khmer text read with an English voice is unintelligible.
- Browsers offer translation only when the language differs from yours, and pick suitable fonts and hyphenation.
- Search engines use it to decide who to show the page to.
Use en for English and km for Khmer. If one section of a page is in
a different language, put lang on that element:
<p>He said, <span lang="km">សួស្តី</span>, and smiled.</p>
4. The head: Information About the Page
The <head> holds metadata: things the browser, search engines, and
social sites need, but that aren't displayed on the page itself. These
are the elements you'll use most.
| Element | What it does |
|---|---|
<meta charset="utf-8"> | Sets the character encoding. Without it, Khmer letters and symbols can show up as garbage (the UTF-8 bytes from How Computers Work). Put it first. |
<meta name="viewport" content="width=device-width, initial-scale=1"> | Tells phones to use the real screen width instead of pretending to be a desktop. Required for responsive design (chapter 11). |
<title> | The text on the browser tab, in bookmarks, and as the headline in search results. Every page needs a unique one. |
<meta name="description" content="…"> | The summary search engines often show under the title. About 150 characters. |
<link rel="stylesheet" href="style.css"> | Loads an external CSS file (chapter 6). |
<link rel="icon" href="favicon.svg"> | The small icon on the tab. |
Add a description to your page now:
<meta name="description" content="Dara Sok is a junior web developer from Phnom Penh.">
Nothing visible changes on the page. The result shows up in the browser tab, search results, and link previews, so it's worth getting right.
5. The body: What People See
Everything displayed in the browser window goes inside <body>:
headings, text, images, buttons, forms. Almost the entire rest of the
HTML part of this series is about what goes inside it.
A common beginner question is "what happens if I put content in <head>
instead?" The browser usually moves it to the body or ignores it. The
rule is simple: head is for information about the page, body is for
the page.
6. Elements, Tags, and Attributes
These three words are often mixed up, so pin them down:
<a href="about.html">About me</a>
└─┬─┘ └─────┬──────┘└───┬───┘└┬─┘
opening attribute content closing
tag tag
└────────────────────┬─────────────────────┘
element
- A tag is the piece in angle brackets:
<a>or</a>. - An element is the opening tag, the content, and the closing tag together.
- An attribute adds extra information to an element. It goes in the
opening tag as
name="value".
Some attributes belong to specific elements (href on <a>, src on
<img>). A few work on every element:
| Attribute | Purpose |
|---|---|
id | A unique name for one element on the page. Used for #fragment links and in CSS. |
class | A reusable label, shared by many elements. The main way to target elements in CSS. |
lang | The language of this element's content. |
title | Extra tooltip text. Don't rely on it for anything important. |
Always put attribute values in quotes, and never reuse an id on the
same page.
7. Nesting and Indentation
Elements contain other elements. This is called nesting, and it forms the tree you saw in DevTools. The one rule: close elements in the reverse order you opened them.
<!-- Correct -->
<p>I like <strong>learning <em>HTML</em></strong>.</p>
<!-- Wrong: the tags overlap -->
<p>I like <strong>learning <em>HTML</strong></em>.</p>
Browsers try to repair overlapping tags, but not always the way you meant. Indent each nested level by two spaces, as in the skeleton above. Indentation means nothing to the browser, but it lets you see the tree at a glance, and mismatched tags become obvious.
Whitespace works in a way that surprises beginners: any number of spaces, tabs, or line breaks in the source collapses into a single space when displayed. Hitting Enter twice doesn't add a gap on the page. Spacing is CSS's job, not HTML's.
8. Void Elements and Comments
Some elements have no content and so need no closing tag. They're called void elements:
<meta charset="utf-8">
<img src="dara.jpg" alt="Dara Sok at a desk">
<br>
<hr>
<input type="text">
Writing <br /> with a trailing slash is allowed but unnecessary in
modern HTML. Don't write </br> or </img>.
Comments leave notes for yourself. The browser ignores them, but anyone can read them through "View source", so don't put secrets in them:
<!-- TODO: replace this with my real photo -->
Comments are also handy for temporarily switching a chunk of HTML off
while you experiment. In VS Code, select the lines and press
Ctrl+/ (Cmd+/ on macOS).
9. Validating Your HTML
Because browsers forgive mistakes silently, you can write broken HTML without knowing it. Two ways to check:
- The W3C validator at validator.w3.org — paste your code under Validate by Direct Input and read the errors. The messages are blunt but accurate.
- DevTools. If the Elements tree doesn't match what you typed, the browser repaired something. Look for the difference.
Make a habit of validating a page before you call it finished.
10. Try It Yourself
- Build from memory. Close your
index.htmland recreate the skeleton in a new file,test.html, without looking. Open it in the browser. What was hard to remember? - Remove the doctype. Delete the first line of
test.htmland reload. In DevTools → Console typedocument.compatMode. It says"BackCompat"in quirks mode and"CSS1Compat"in standards mode. Put it back and check again. - Break the encoding. Add
<p>សួស្តី, world</p>, then delete<meta charset="utf-8">. Does the Khmer text break? (It depends on how your editor and browser are set up — try both ways.) Restore the tag afterwards. - Validate. Paste your
index.htmlinto the W3C validator. Fix anything it reports. Add thedescriptionmeta tag from this chapter and commit.
Next, we'll fill the body with real content: headings, paragraphs, lists, links, and images.
Buy Me a Coffee
Found this tutorial helpful? Consider buying me a coffee to support more free content!