Skip to main content
ANVISoftware Solutions
Lesson 1 of 20Beginner12 min

HTML Document Structure

By the end of this lesson

Build a valid page and explain what each part of the document does.

An HTML file is a document, and a browser expects that document in a particular shape. There is a declaration at the top, one element that wraps everything, and two regions inside it.

Learn that shape once and you can open any page, read its first ten lines, and know what is going on. This lesson is about the wrapper rather than the content that goes inside it.

The smallest page worth writing
HTML
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Employee Directory</title>
  </head>
  <body>
    <h1>Employee Directory</h1>
    <p>12 people across 3 departments.</p>
  </body>
</html>
  • Line 1 is the doctype. It is not a tag and it has no closing partner. It tells the browser to use modern rendering rules rather than a compatibility mode kept alive for pages written in the 1990s.
  • Line 2 opens the html element, which contains everything else. The lang attribute states what language the page is written in.
  • Lines 3 to 7 are the head: information about the page. Nothing here appears on screen.
  • Line 4 declares the character encoding, which decides how the bytes in your file turn into letters.
  • Line 5 is the viewport declaration, covered below. This is the line that decides whether the page is usable on a phone.
  • Line 6 is the title, shown in the browser tab, in bookmarks and in search results.
  • Lines 8 to 11 are the body: everything the reader actually sees.

The seven parts, and what each one is responsible for:

<!DOCTYPE html>
Selects standard rendering. Leave it out and the browser switches to a legacy mode where some CSS behaves differently, which produces layout bugs that are very hard to explain.
<html lang="en">
The root element. The lang attribute tells a screen reader which pronunciation rules to use, and tells the browser which dictionary to spell-check against. "en-GB" and "en-US" are both valid and more specific.
<head>
Metadata and resources: the title, the encoding, the viewport, links to stylesheets, references to scripts. Content placed here does not display.
<meta charset="utf-8">
Says the file is UTF-8, the encoding that covers every character you are likely to need. Put it early — the browser has to know the encoding before it can read much else.
<meta name="viewport" ...>
Tells a mobile browser to lay the page out at the real width of the device instead of pretending to be a desktop window.
<title>
The name of this page. It is also the first thing a screen reader announces on arrival, so make it describe the page, not the site.
<body>
The visible document. Headings, text, images, forms, everything.

Valid markup is not pedantry, and it is worth understanding why. A browser will never refuse to display your page. If a tag is unclosed or nested wrongly, it repairs the damage and carries on. That sounds generous, and it is the reason broken markup survives for years without anyone noticing.

The problem is that the repaired result is what everything else works from. CSS selectors match the repaired tree. JavaScript reads the repaired tree. Assistive technology describes the repaired tree. And browsers, crawlers, embedded web views and email clients do not all repair in the same way, so a page that looks correct on your machine can be structured differently somewhere else.

You do not need to memorise the rules. Run your page through a validator when something behaves oddly, and check the elements you actually see in the browser's element inspector rather than the text you wrote.

A realistic head for the directory page
HTML
<!DOCTYPE html>
<html lang="en-GB">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Employee Directory — Anvi Internal Tools</title>
    <meta
      name="description"
      content="Search employees by name, department or office location."
    />
    <link rel="stylesheet" href="/styles/directory.css" />
    <script src="/scripts/directory.js" defer></script>
  </head>
  <body>
    <h1>Employee Directory</h1>
    <!-- Search, filters and the employee list go here -->
  </body>
</html>
  • The description is not shown on the page. Search engines often use it as the summary under your link.
  • The stylesheet is linked in the head so the browser can fetch it while it is still reading the HTML. That is what avoids a flash of unstyled text.
  • defer on the script means: download it alongside the HTML, but do not run it until the document has been parsed. Without defer, the script runs before the body exists and cannot find any of the elements it wants to work with.
  • lang="en-GB" is more specific than "en". It affects spell-checking and screen reader pronunciation.

Summary

  • Every page has the same wrapper: doctype, html with lang, head for metadata, body for content
  • The viewport declaration is what makes a page lay out at real device width instead of being scaled down
  • Declare UTF-8 early, or characters such as currency symbols arrive mangled
  • Browsers repair broken markup rather than rejecting it, and not every consumer repairs it the same way
  • Load scripts with defer so the document exists by the time they run

Practice

Attempt each one before opening the solution. Getting it wrong first is how the idea sticks.

Try it yourself

Build a page shell from memory

Without copying from above, write the complete wrapper for a second page in the same tool: an expense list. British English, a title that says what the page is, a description, one stylesheet and one script.

Open it in a browser, then narrow the window to phone width. Now delete the viewport line, reload, and compare.

Show solution

The shape is fixed, so this becomes muscle memory quickly. The part worth thinking about is the title: "Expenses" tells the reader very little, and "Anvi Internal Tools" tells them nothing about this page. Lead with the page, then the context.

When you removed the viewport line the layout did not break — it was laid out for a wide window and then scaled down. That distinction matters, because it means the fix is the missing line rather than your CSS.

HTML
<!DOCTYPE html>
<html lang="en-GB">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Expense Claims — Anvi Internal Tools</title>
    <meta
      name="description"
      content="Review, submit and approve employee expense claims."
    />
    <link rel="stylesheet" href="/styles/expenses.css" />
    <script src="/scripts/expenses.js" defer></script>
  </head>
  <body>
    <h1>Expense Claims</h1>
  </body>
</html>

Think about it

Think about it

A colleague says validation does not matter because the page renders correctly in Chrome. Give two concrete reasons that is not a safe conclusion.

Show solution

First, rendering correctly and being structured correctly are different things. The browser repaired your markup to produce that render, so your CSS and JavaScript are now written against a tree you did not author. The next change can move things unexpectedly.

Second, the browser is not the only consumer. Assistive technology, search crawlers and in-app web views all read the document, and they do not all recover from the same mistake identically.

There is a fair version of the argument, though: not every validator warning is worth acting on. Structural errors — unclosed elements, invalid nesting, duplicate ids — are worth fixing. Pedantic advice about attribute ordering is not.

Knowledge check

Nothing is recorded and there is no score. The explanation appears either way.

A site looks correct on a laptop but arrives on a phone tiny and zoomed out. What is the most likely cause?
What belongs in the head rather than the body?

Saved in this browser only.