Part 1: Document Structure — DOCTYPE, head, body, metadata
Introduction
HTML was the first language I touched when I started building things for the web. Everything else — CSS, JavaScript, Python backends, React components — was layered on top of that foundation later. Years of building static documentation sites, tool report pages, and web UIs taught me a consistent lesson: if you don't understand the document structure, you end up fighting the browser instead of working with it.
This part covers the anatomy of an HTML document: what every file needs, what the browser actually parses, and the metadata that controls how your page behaves before a user even sees it.
What HTML Actually Is
HTML (HyperText Markup Language) is not a programming language. It is a markup language — a way to describe the structure and meaning of content using elements (tags). Browsers read the HTML you write, construct a Document Object Model (DOM) tree from it, and use that tree to render what the user sees.
Understanding this matters because:
CSS selects elements in the DOM tree
JavaScript manipulates the DOM tree
Accessibility tools (screen readers) traverse the DOM tree
Search engines index content from the DOM tree
If the HTML structure is wrong, everything sitting on top of it breaks.
The Minimal Valid HTML5 Document
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Page Title</title>
</head>
<body>
<p>Hello, world.</p>
</body>
</html>Every HTML file I write starts with exactly this skeleton. Each piece has a specific reason to be there.
<!DOCTYPE html>
<!DOCTYPE html>This declaration tells the browser which version of HTML the document follows. For HTML5 (the current standard), it is always:
Without it, browsers fall into quirks mode — a compatibility mode that emulates old browser behavior from the late 1990s. Layouts break in inconsistent ways, spacing behaves differently, and certain CSS properties stop working as expected.
This is always the first line. It has no closing tag.
The <html> Element
<html> ElementThe <html> element is the root of the document. Every other element lives inside it.
The lang attribute declares the page's primary language. This is not cosmetic:
Screen readers use it to select the correct pronunciation engine
Browser translation tools use it to determine whether to prompt
Search engines use it for multilingual indexing
Use a valid BCP 47 language tag:
English
en
French
fr
Japanese
ja
Thai
th
Chinese (Simplified)
zh-Hans
The <head> Element
<head> ElementThe <head> contains metadata — information about the document that is not rendered as visible content.
Character Encoding
This must be the first element inside <head>. It tells the browser how to decode the document's bytes into characters.
UTF-8 is the universal choice. It handles every language, emoji, and symbol correctly. Without this declaration, browsers default to a locale-specific encoding, which breaks non-ASCII characters.
Viewport
Without this, mobile browsers render pages at a desktop-width virtual viewport (typically 980px) then scale it down. The result is tiny text and a bad user experience.
This declaration tells the browser to match the viewport width to the device's actual screen width and start at 1× zoom.
Page Title
The <title> element sets the text shown in:
The browser tab
Bookmarks
Search engine results (as the clickable headline)
Screen reader announcements when the page loads
Every page needs a unique, descriptive title.
Common <head> Elements
<head> ElementsBeyond the minimum, <head> typically contains additional metadata:
External CSS
Favicon
Author and Description (SEO)
Open Graph (Social Sharing)
Open Graph tags control what appears when someone shares a link on Slack, Twitter, LinkedIn, or other platforms that render link previews.
The <body> Element
<body> ElementThe <body> contains everything rendered on screen: text, images, headings, links, forms — all visible content.
HTML comments use <!-- --> syntax. They are not rendered but are visible in the page source.
HTML Element Anatomy
Before moving further, it is important to understand the terminology:
Opening tag
<p class="intro">
Starts the element
Attribute
class="intro"
Modifies element behaviour or meaning
Content
This is a paragraph.
The element's content
Closing tag
</p>
Ends the element
Some elements are void elements — they have no content and no closing tag:
The trailing / before > is optional in HTML5 but I include it habitually for clarity.
Nesting Rules
HTML elements nest inside each other, forming the tree structure the browser parses into the DOM.
Correct nesting:
Incorrect nesting (overlapping tags):
Browsers attempt to auto-correct bad nesting, but the corrections they apply differ between browsers. The result is inconsistent rendering. Write correctly structured HTML and the browser behaviour is predictable.
Block vs. Inline Elements
HTML elements have a default display behaviour:
Block elements take the full available width and force a line break before and after:
<p>,<div>,<h1>–<h6>,<ul>,<ol>,<li>,<table>,<form>,<section>,<article>,<header>,<footer>,<main>,<nav>
Inline elements only take up as much width as their content and do not force line breaks:
<span>,<a>,<strong>,<em>,<code>,<img>,<button>,<input>,<label>
This distinction matters because you cannot validly place a block element inside an inline element:
HTML Entities
Certain characters have special meaning in HTML and must be escaped to appear as literal text:
<
<
Less-than sign in text
>
>
Greater-than sign in text
&
&
Ampersand in text
"
"
Double quote inside attribute
'
' or '
Single quote inside attribute
Non-breaking space
Prevent line break between words
Putting It Together: A Real Page Skeleton
This is the template I use when starting any static HTML page:
A few things to note:
<script>goes at the end of<body>(or usesdefer) so it does not block page renderingSemantic structure (
<header>,<main>,<footer>) is established at the skeleton levelEvery page has a unique
<title>and<meta name="description">
Summary
<!DOCTYPE html>
Activates standards mode — always first
lang attribute
Required for accessibility and i18n
charset="UTF-8"
Must be first in <head> — enables all characters
viewport meta
Required for correct mobile rendering
<title>
Unique per page — tab, bookmark, search result
Block vs inline
Determines layout flow and valid nesting
Void elements
No closing tag needed
Entities
Escape <, >, & in text content
Up Next
Part 2 covers semantic HTML — using the right elements to give content meaning, not just structure.
Last updated