HTML Document Structure: Doctype, html, head, body, meta charset and viewport
The five lines at the top of every HTML file are not decoration. Here is what the doctype, the html/head/body split, meta charset, and the viewport tag each do — why the browser misbehaves when you leave one out, and how to reason about the cases that trip people up.
What the HTML5 boilerplate actually does
Every HTML page starts with the same handful of lines — <!doctype html>, then <html> wrapping a <head> and a <body>, with <meta charset> and <meta name="viewport"> inside the head. That block is not a ritual: each line answers a specific question the browser has to settle before it can render anything — which rendering rules to follow, which bytes map to which characters, and how wide to pretend the screen is.
Here is the whole thing, and then what each piece is for:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Study Notes</title>
</head>
<body>
<p>Hello.</p>
</body>
</html>
The doctype
<!doctype html> is not an element. It has no attributes, no closing tag, and no version number. Its one job is to keep the browser out of quirks mode — a legacy compatibility mode that emulates Navigator 4 and IE5 layout, with a different box model and different table and image spacing. Write it and you get no-quirks (standards) mode; omit it, misspell it, or let content appear in front of it, and the browser can drop into quirks mode, where perfectly good CSS lays out wrong. (A third mode, limited-quirks, is what certain legacy doctypes select; <!doctype html> never selects it.) The keyword is case-insensitive, so <!DOCTYPE html> is equally fine — but it must come first in the file, with nothing but whitespace before it.
html, head, and body
<html> is the root element — everything else is a descendant of it, and there is exactly one per document. It carries the document's lang attribute (lang="en"), which tells screen readers which pronunciation rules to use and helps translation tools.
Inside it, the document splits in two. <head> holds metadata — information about the page rather than content shown in it: the <title>, <meta> elements, <link> to stylesheets, and <script> tags. A normal HTML document must contain exactly one <title>. <body> holds everything the user actually sees. There is one head and one body per document, in that order.
One subtlety worth filing away: the <head> and <body> tags are optional in the HTML syntax, even though the elements are not. Leave the tags out and the parser infers both elements anyway, so the resulting DOM is the same. Writing them is still the better habit, because it keeps your source looking like the tree you will inspect in DevTools.
meta charset
<meta charset="utf-8"> tells the parser how to turn raw bytes into characters. In HTML, the value must be an ASCII case-insensitive match for utf-8 — UTF-8 is the only conforming encoding. Placement matters: the declaration must sit entirely within the first 1024 bytes of the document, which is why it goes first inside <head>. Get this wrong and you see the classic mojibake — curly quotes rendered as ’.
The viewport meta tag
<meta name="viewport" content="width=device-width, initial-scale=1"> tells a phone to lay the page out at the real width of the screen and display it at 100% zoom. Without it, mobile browsers assume they are showing a desktop site: they use a virtual viewport around 980 CSS pixels wide, then shrink the result to fit. Your responsive CSS still "works" — it just never triggers, because the layout viewport is never narrow. This is one of the most common reasons a media-query layout looks fine in a resized desktop window and broken on an actual phone.
Full course context lives in the WGU D276 Web Development Foundations study guide. Try the questions below, then keep going.
Practice: Html Document Structure
-
What is the purpose of the <!doctype html> declaration at the top of an HTML5 page?
- It switches the browser into no-quirks (standards) mode so layout follows modern HTML and CSS specifications
- It tells the browser which version of HTML the page uses so the browser can load the matching DTD and validate the markup
- It is the true root element of the document, with <html> nested inside it as its only child
- It declares the document's character encoding early, before the parser reaches the <head> element
Show answer & explanation
Correct answer: It switches the browser into no-quirks (standards) mode so layout follows modern HTML and CSS specifications. The HTML5 doctype exists for exactly one reason: to keep the browser out of quirks mode, a legacy rendering mode with a different box model and different image and table spacing. The DTD answer is the tempting one because pre-HTML5 doctypes really did point at a Document Type Definition — but <!doctype html> contains no version number and no DTD reference, and browsers never validated against DTDs anyway. Encoding is declared separately by <meta charset>.
-
You put <meta charset="utf-8"> near the bottom of a long <head> block, after a large inline <style> element, and accented characters render as garbled symbols. Why?
- The character encoding declaration must appear entirely within the first 1024 bytes of the document, and the inline styles pushed it past that limit
- A <meta> element is only honored when it appears before any <link> or <style> element, regardless of byte position
- <meta charset> must be the first child of <html>, placed before the <head> element opens
- Encoding declarations that appear after the <title> element are ignored by the HTML parser
Show answer & explanation
Correct answer: The character encoding declaration must appear entirely within the first 1024 bytes of the document, and the inline styles pushed it past that limit. The HTML Standard requires the character encoding declaration to be located entirely within the first 1024 bytes of the document, because the parser has to commit to an encoding almost immediately; a big inline stylesheet ahead of it can push it out of range. The ordering-based distractors sound like plausible rules but no such rules exist — position is measured in bytes, not in element order. And <meta> is metadata content, so it cannot be a direct child of <html> at all: the content model of <html> is a head followed by a body.
-
A responsive page has no <meta name="viewport"> tag. What happens when a phone loads it?
- The browser lays the page out in a virtual viewport around 980 CSS pixels wide and scales the result down, so text looks tiny and narrow-width media queries never match
- The browser lays the page out at the device's actual width but ignores every media query in the stylesheet
- The page renders at the device width as normal, but pinch-to-zoom is disabled until a viewport tag is added
- The browser falls back to a 320-pixel viewport, so a wide desktop layout gets clipped on the right
Show answer & explanation
Correct answer: The browser lays the page out in a virtual viewport around 980 CSS pixels wide and scales the result down, so text looks tiny and narrow-width media queries never match. Mobile browsers assume an unmarked page is an old desktop site, so they lay it out in a wide virtual viewport (about 980 CSS pixels) and shrink the rendering to fit the screen. Media queries are not ignored — that is the seductive wrong answer — they simply never match, because the layout viewport reports the wide virtual width rather than the narrow device width. The result is a readable-but-microscopic desktop layout, not a clipped one.
-
A file contains only this markup: <!doctype html>, then <html lang="en">, then <title>Notes</title>, then <p>Hello</p>, then </html>. What does the resulting DOM look like?
- The parser implies the missing elements: <title> ends up inside a generated head and <p> inside a generated body, so both document.head and document.body exist
- document.head is null, because an element cannot exist in the DOM without a start tag in the source
- The missing head and body start tags trigger quirks mode, overriding the doctype
- Both <title> and <p> land in body, because a head element is only created when its tags are written explicitly
Show answer & explanation
Correct answer: The parser implies the missing elements: <title> ends up inside a generated head and <p> inside a generated body, so both document.head and document.body exist. The head and body start and end tags are optional in the HTML syntax — the head start tag may be omitted when the first thing inside is an element, and the body start tag when the first thing inside is not whitespace, a comment, or a head-only element. The parser therefore puts <title> in an implied head and switches to an implied body the moment it meets flow content like <p>, giving a DOM identical to the fully tagged version. Quirks mode is decided by the doctype, not by omitted tags. Note that a start tag can never be omitted if it carries attributes, which is one reason <html> is written out here — it holds lang.
-
A page with no byte order mark is served with the HTTP header Content-Type: text/html; charset=ISO-8859-1, but the file itself contains <meta charset="utf-8">. Which encoding does the browser use?
- ISO-8859-1, because an encoding supplied by the transport layer outranks the in-document meta declaration
- UTF-8, because a declaration inside the document is more specific than a server header
- Neither — the conflict makes the browser fall back to autodetecting the encoding from the content
- Neither — the browser halts parsing and reports an encoding-mismatch error
Show answer & explanation
Correct answer: ISO-8859-1, because an encoding supplied by the transport layer outranks the in-document meta declaration. In the encoding sniffing algorithm, a byte order mark comes first, then any user override, then the transport layer (the HTTP Content-Type charset, confidence certain), and only after that the prescan for <meta charset>. So a server header set to ISO-8859-1 wins and your UTF-8 meta tag is never reached. This is why a page can look correct locally and turn to mojibake once deployed — the fix is to correct the server's Content-Type header, not to move the meta tag.
-
What is the problem with <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">?
- It tries to switch off pinch-to-zoom, an accessibility barrier for people with low vision — which is why mobile browsers now override it — so drop both restrictions and keep width=device-width, initial-scale=1
- Nothing — locking the scale is the recommended setting because it prevents layout shift when the device is rotated
- It suppresses media queries for widths below the maximum scale, so the mobile stylesheet never applies
- It forces the layout viewport back to the default 980-pixel virtual width, cancelling width=device-width
Show answer & explanation
Correct answer: It tries to switch off pinch-to-zoom, an accessibility barrier for people with low vision — which is why mobile browsers now override it — so drop both restrictions and keep width=device-width, initial-scale=1. maximum-scale=1 and user-scalable=no both exist to switch zooming off, and MDN warns that doing so prevents people experiencing low vision from reading page content, while WCAG requires at least 2x scaling. Browsers have pushed back — iOS has ignored user-scalable=no by default since iOS 10, and browser settings can override it elsewhere — but relying on the browser to undo your own markup is not the fix; removing the restrictions is. The rotation answer is tempting because scale locking does suppress some resize behavior, and that is exactly the trade people talk themselves into. Zoom settings have no effect on media-query evaluation, and they do not cancel width=device-width.
Reading a boilerplate line by line
Take this head and ask what breaks if you delete each line:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Course Notes</title>
<link rel="stylesheet" href="styles.css">
</head>
| Remove this | Symptom you would see |
|---|---|
<!doctype html> | Quirks mode; widths and spacing come out subtly wrong and document.compatMode reads "BackCompat" instead of "CSS1Compat" |
lang="en" | Page still renders; a screen reader falls back to its default language and may apply the wrong pronunciation rules |
<meta charset> | Apostrophes and dashes turn into ’-style garbage, unless the server happens to send the right charset header |
<meta name="viewport"> | Desktop-width layout shrunk to fit the phone; narrow-width media queries never match |
<title> | Non-conforming document; the browser tab falls back to the file name or URL, and search engines have to invent a heading from the page content |
Mistakes people actually make
Putting visible content in the head. Write a <p> or an <h1> inside <head> and nothing errors out — the parser silently ends the head at that point and starts the body. Everything you wrote afterwards, stylesheet links included, is inside <body> in the DOM even though your source shows it in the head. Browsers do still honour a <link rel="stylesheet"> there, so the page may look fine while the inspector shows a tree that does not match your file; a validator is what flags it, because the document is no longer conforming.
Confusing the two meta tags. charset is a standalone attribute (<meta charset="utf-8">) with no name or content. The viewport tag is a name/content pair. Mixing them — <meta name="charset" content="utf-8"> — declares nothing, because charset is not a defined metadata name.
Treating the doctype as an element. There is no </doctype>, and it goes above <html>, never inside the head. Leading whitespace is ignored, but any real content in front of it puts the browser into quirks mode — a classic cause is a server-side include or a stray blank line emitted by a template before the first tag.
Reasoning about the tricky cases
When something in the boilerplate misbehaves, ask when the browser needs that information. Encoding is needed before any text is decoded, which is why the 1024-byte rule exists and why an HTTP header — available before the file body arrives — outranks a tag inside the file. Rendering mode is needed before the first box is laid out, which is why the doctype must be the very first thing. The viewport is needed before layout too, but it only matters on devices that would otherwise fake a wide screen, which is why the bug hides on desktop and only shows up on a phone.
For the specifications themselves, see MDN on the viewport meta element and quirks mode and standards mode. When you are ready for more repetition, work through the rest of the D276 practice questions.
Want someone to walk you through this?
Book 1-on-1 prep for WGU D276 — original coaching, never exam content.
Stuck on this topic? WhatsApp us on +1 646 980 4914.
Working through the whole course? Read the full WGU D276 study guide, or see every WGU D276 practice topic.