Document Structure & Metadata - HTML reference 2026 vdsology
- Chapter 2 — Document Structure & Metadata
Chapter 2 — Document Structure & Metadata
This chapter covers the elements that form the invisible scaffolding of every HTML page — the document type declaration, the
<html>,<head>, and<body>shells, and every metadata element that lives in the<head>. These elements configure how browsers parse, render, and index your page.
2.1 — The Document Type Declaration
<!DOCTYPE html>
Must be the absolute first thing in every HTML document. Triggers standards mode rendering in browsers. Without it, browsers use “quirks mode” — an emulation of 1990s buggy browser behaviour.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Page Title</title>
</head>
<body>
…
</body>
</html>
2.2 — <html>
The root element. All other elements are descendants of <html>.
Key attributes:
lang— Document language (critical for accessibility and SEO). Value: BCP 47 tag (en,en-GB,fr, etc.)dir— Base text direction:ltr,rtl,auto
<!DOCTYPE html>
<html lang="en" dir="ltr">
Nesting rules: Must contain exactly one <head> and one <body>, in that order.
2.3 — <head>
Container for all metadata — information about the document rather than its content. Nothing inside <head> renders visually (except <title>, which appears in the browser tab).
Nesting rules: Must be the first child of <html>. Contains metadata elements: <title>, <base>, <link>, <meta>, <style>, <script>, <noscript>, <template>.
Required minimum <head> content:
<meta charset="UTF-8">— must be first<title>— required for valid HTML
2.4 — <title>
The document’s title — displayed in the browser tab, used as the default bookmark name, and the primary result title in search engines.
No element-specific attributes — globals only.
Content model: Text only — no HTML markup.
<title>Understanding CSS Grid — MDN Web Docs</title>
<title>Cart (3 items) — My Shop</title>
<title>Dashboard — Admin — ACME Corp</title>
Rules:
- Required — a document without
<title>is invalid - Must be non-empty
- Must be unique per page for navigation and SEO
- Update dynamically for SPAs:
document.title = 'New Title'
2.5 — <base>
Sets the base URL for all relative URLs in the document, and/or the default target for all links. Only one <base> per document. Must appear before any elements that use URLs.
Attributes:
href
The base URL. All relative URLs in the document are resolved relative to this URL.
<base href="https://www.example.com/products/">
<!-- <a href="widget.html"> now resolves to https://www.example.com/products/widget.html -->
target
Default browsing context for links and forms that don’t specify their own target.
Values: _self (default), _blank, _parent, _top, or a named frame.
<base href="https://example.com/" target="_blank">
2.6 — <link>
Defines relationships between the current document and an external resource. Most commonly used to load stylesheets, define favicons, and provide resource hints.
Attributes:
rel (required)
Defines the relationship. Multiple values can be space-separated.
Core values:
rel value |
Purpose |
|---|---|
stylesheet |
Load a CSS stylesheet |
icon |
Favicon / app icon |
apple-touch-icon |
iOS home screen icon |
preload |
Preload a critical resource (high priority, required for current page) |
modulepreload |
Preload a JavaScript module and its dependencies |
prefetch |
Low-priority prefetch for likely future navigation |
preconnect |
Pre-establish connection to origin (DNS + TCP + TLS) |
dns-prefetch |
DNS lookup only — lighter than preconnect |
manifest |
Link to Web App Manifest (manifest.json) |
canonical |
The canonical URL for duplicate/similar pages (SEO) |
alternate |
Alternate representation (RSS feed, translated page, print version) |
next / prev |
Next/previous page in a sequence (pagination) |
author |
Document author’s page |
license |
License information |
search |
OpenSearch description for site search |
pingback |
Pingback server URL |
expect |
Block rendering until a specific DOM element is parsed (used with blocking="render") |
href
URL of the linked resource.
type
MIME type of the linked resource. For stylesheets: text/css. For icons: image/png, image/svg+xml.
media
Media query — load this resource only when the query matches.
<link rel="stylesheet" href="print.css" media="print">
<link rel="stylesheet" href="dark.css" media="(prefers-color-scheme: dark)">
as
Required with rel="preload" and rel="modulepreload". Specifies the resource type for correct prioritisation and Content-Type matching.
Values: audio, document, embed, fetch, font, image, object, script, style, track, video, worker
<link rel="preload" href="hero.webp" as="image" fetchpriority="high">
<link rel="preload" href="main.js" as="script">
<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>
crossorigin
CORS setting for the linked resource.
Values: anonymous or use-credentials
Required for <link rel="preload" as="font"> — fonts always require CORS.
integrity
Subresource Integrity (SRI) hash — browser verifies the resource matches the hash before using it. Prevents supply-chain attacks.
<link rel="stylesheet"
href="https://cdn.example.com/styles.css"
integrity="sha384-abc123..."
crossorigin="anonymous">
referrerpolicy
Controls the Referer header when fetching the resource.
Values: no-referrer, no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
hreflang
Language of the linked resource. Used with rel="alternate" for international SEO.
<link rel="alternate" hreflang="fr" href="https://example.fr/">
<link rel="alternate" hreflang="de" href="https://example.de/">
<link rel="alternate" hreflang="x-default" href="https://example.com/">
imagesrcset and imagesizes
Used with rel="preload" as="image" for responsive image preloading.
<link rel="preload" as="image"
imagesrcset="hero-400.webp 400w, hero-800.webp 800w"
imagesizes="(max-width: 600px) 400px, 800px">
sizes
For rel="icon" — specifies icon sizes. any = scalable (SVG).
<link rel="icon" href="favicon.svg" type="image/svg+xml" sizes="any">
<link rel="icon" href="favicon-32.png" type="image/png" sizes="32x32">
<link rel="apple-touch-icon" href="apple-180.png" sizes="180x180">
disabled
Boolean. For rel="stylesheet" — prevents the stylesheet from being applied without removing it from the DOM.
<link rel="stylesheet" href="dark-theme.css" disabled id="dark-theme-link">
<script>
document.getElementById('dark-theme-link').disabled = false; // enable dark theme
</script>
fetchpriority
Controls fetch priority for the resource.
Values: high, low, auto (default)
<link rel="preload" href="hero.webp" as="image" fetchpriority="high">
<link rel="prefetch" href="next-page.html" fetchpriority="low">
blocking
Signals that the resource must be fetched before rendering.
Value: render
<link rel="stylesheet" href="critical.css" blocking="render">
<link rel="expect" href="#hero-section" blocking="render">
rel="expect" with blocking="render" — Complete Explanation
rel="expect" is used to mark a specific element in the document as a render-blocking dependency — the browser will not render anything until that element has been parsed.
<head>
<!-- Don't render until #hero-section has been parsed -->
<link rel="expect" href="#hero-section" blocking="render">
<link rel="expect" href="#main-nav" blocking="render">
</head>
<body>
<nav id="main-nav">…</nav>
<section id="hero-section">
<h1>Welcome</h1>
</section>
</body>
How it differs from blocking="render" on <script>/<style>:
<script blocking="render">/<style blocking="render">— blocks until the resource loads<link rel="expect" blocking="render">— blocks until a DOM element with that id is parsed — no external resource
rel="pingback"
Links to a pingback server — a URL that receives XML-RPC notifications when another page links to your page. Used in blog/CMS ecosystems (WordPress).
<link rel="pingback" href="https://example.com/xmlrpc.php">
2.7 — <meta>
Provides metadata that cannot be expressed by <title>, <base>, <link>, <style>, or <script>.
charset
Specifies the character encoding. Must be UTF-8. Must be the first element in <head>, before <title>.
<meta charset="UTF-8">
name + content
General metadata key-value pairs.
Core name values:
name |
Purpose |
|---|---|
description |
Page description (shown in search results) |
keywords |
Comma-separated keywords (mostly ignored by search engines) |
author |
Document author name |
generator |
Software that generated the page |
referrer |
Default referrer policy |
robots |
Instructions for web crawlers |
theme-color |
Browser chrome colour (mobile) |
color-scheme |
Supported colour schemes (light, dark, light dark) |
viewport |
Viewport configuration (see below) |
application-name |
Name of the web application |
creator |
Creator of the document |
publisher |
Publisher name |
rating |
Content rating |
Viewport meta (critical for responsive design):
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Viewport content tokens:
| Token | Values | Purpose |
|---|---|---|
width |
device-width or pixels |
Viewport width |
height |
device-height or pixels |
Viewport height |
initial-scale |
1.0 |
Initial zoom level |
minimum-scale |
0.1–10 |
Minimum zoom |
maximum-scale |
0.1–10 |
Maximum zoom (never set to 1 — disables pinch zoom) |
user-scalable |
yes, no |
Allow user zoom (never no — accessibility violation) |
interactive-widget |
overlays-content, resizes-visual, resizes-content |
Virtual keyboard behaviour |
Robots meta:
<meta name="robots" content="index, follow">
<meta name="robots" content="noindex, nofollow">
<meta name="robots" content="noindex, follow, noarchive">
Robots tokens: index, noindex, follow, nofollow, noarchive, nosnippet, noimageindex, max-snippet:n, max-image-preview:none|standard|large, max-video-preview:n
Theme colour:
<meta name="theme-color" content="#2563eb">
<meta name="theme-color" content="#1e293b" media="(prefers-color-scheme: dark)">
Colour scheme:
<meta name="color-scheme" content="light dark">
http-equiv + content
Simulates HTTP response headers.
http-equiv |
Purpose |
|---|---|
content-type |
Declare encoding (use <meta charset> instead) |
refresh |
Redirect or refresh after delay |
x-ua-compatible |
IE compatibility mode (IE=edge) |
content-security-policy |
Apply a CSP via meta tag |
<meta http-equiv="refresh" content="5; url=https://example.com/new-page">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta http-equiv="content-security-policy" content="default-src 'self'">
Open Graph (property + content)
<meta property="og:title" content="Page Title">
<meta property="og:description" content="Page description.">
<meta property="og:image" content="">
<meta property="og:url" content="https://example.com/page">
<meta property="og:type" content="article">
<meta property="og:site_name" content="Site Name">
Twitter Card
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Title">
<meta name="twitter:description" content="Description">
<meta name="twitter:image" content="">
2.8 — <style>
Embeds CSS directly in the HTML document.
Attributes:
| Attribute | Values | Purpose |
|---|---|---|
media |
Media query string | Apply styles only when query matches |
nonce |
Cryptographic nonce | CSP compliance for inline styles |
blocking |
render |
Block rendering until styles are parsed |
<style>
body { font-family: system-ui, sans-serif; }
</style>
<style media="print">
nav, footer { display: none; }
</style>
<style blocking="render">
/* Critical CSS — render blocked until this is parsed */
.hero { min-height: 100svh; }
</style>
2.9 — <script>
Embeds or links JavaScript (or other script types).
Attributes:
| Attribute | Values / Purpose |
|---|---|
src |
URL of external script |
type |
Script MIME type or keyword (see below) |
async |
Boolean — load asynchronously; execute as soon as loaded |
defer |
Boolean — load in background; execute after HTML is parsed |
nomodule |
Boolean — only executed by browsers that do NOT support ES modules |
crossorigin |
anonymous or use-credentials |
integrity |
SRI hash for external scripts |
referrerpolicy |
Referrer policy for fetching the script |
nonce |
CSP nonce for inline scripts |
blocking |
render — block rendering until script loads and executes |
fetchpriority |
high, low, auto |
type attribute values:
type value |
Purpose |
|---|---|
Omitted or text/javascript |
Classic JavaScript |
module |
ES module — deferred by default, supports import/export, strict mode |
importmap |
Defines import specifier mappings for ES modules |
speculationrules |
JSON defining prefetch/prerender rules |
| Any other MIME type | Not executed — stored as data |
<!-- Classic: deferred for performance -->
<script src="main.js" defer></script>
<!-- Module: deferred by default -->
<script type="module" src="app.js"></script>
<!-- Import map: must appear before any module scripts -->
<script type="importmap">
{
"imports": {
"react": "https://esm.sh/react@18",
"react-dom": "https://esm.sh/react-dom@18"
}
}
</script>
<!-- Speculation rules: browser prefetch/prerender hints -->
<script type="speculationrules">
{
"prerender": [
{ "where": { "href_matches": "/products/*" }, "eagerness": "moderate" }
]
}
</script>
<!-- async: load and execute ASAP, non-blocking -->
<script src="analytics.js" async></script>
<!-- SRI for external scripts -->
<script src="https://cdn.example.com/lib.js"
integrity="sha384-abc123..."
crossorigin="anonymous"></script>
<!-- nomodule: fallback for old browsers that don't support modules -->
<script type="module" src="modern.js"></script>
<script nomodule src="fallback.js"></script>
async vs defer comparison:
async |
defer |
|
|---|---|---|
| Fetch | Parallel with HTML parsing | Parallel with HTML parsing |
| Execute | As soon as loaded (can interrupt parsing) | After HTML fully parsed |
| Order | No guaranteed order | In source order |
| Use for | Independent scripts (analytics, ads) | App scripts with dependencies |
2.10 — <noscript>
Provides fallback content for when JavaScript is disabled or unavailable. Behaviour differs by context:
In <head>: Can contain <link>, <style>, <meta> elements.
In <body>: Can contain any flow content.
<!-- In head: load stylesheet only if JS disabled -->
<noscript>
<link rel="stylesheet" href="no-js.css">
</noscript>
<!-- In body: show message if JS disabled -->
<noscript>
<p class="no-js-warning">
JavaScript is disabled. Some features may not work.
<a href="/enable-js">Learn how to enable JavaScript</a>
</p>
</noscript>
2.11 — The Complete Recommended <head> Boilerplate
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<!-- 1. Character encoding: MUST be first, before <title> -->
<meta charset="UTF-8">
<!-- 2. Viewport: critical for responsive design -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 3. Title: required; unique per page -->
<title>Page Title — Site Name</title>
<!-- 4. Description: shown in search results -->
<meta name="description" content="A clear, concise description under 160 characters.">
<!-- 5. Colour scheme: before stylesheets to prevent flash -->
<meta name="color-scheme" content="light dark">
<!-- 6. Theme colour: mobile browser chrome -->
<meta name="theme-color" content="#2563eb"
media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#1e40af"
media="(prefers-color-scheme: dark)">
<!-- 7. Canonical URL: for SEO deduplication -->
<link rel="canonical" href="https://example.com/current-page">
<!-- 8. Favicon -->
<link rel="icon" href="/favicon.svg" type="image/svg+xml" sizes="any">
<link rel="icon" href="/favicon-32.png" type="image/png" sizes="32x32">
<link rel="apple-touch-icon" href="/apple-touch-icon.png" sizes="180x180">
<!-- 9. Web App Manifest -->
<link rel="manifest" href="/manifest.json">
<!-- 10. Preconnect to critical third-party origins -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="dns-prefetch" href="https://analytics.example.com">
<!-- 11. Preload critical resources -->
<link rel="preload" href="/fonts/inter-var.woff2"
as="font" type="font/woff2" crossorigin fetchpriority="high">
<link rel="preload" href="/images/hero.webp"
as="image" fetchpriority="high">
<!-- 12. Critical CSS (inline or linked) -->
<style>
/* Critical above-fold styles */
* { box-sizing: border-box; }
body { margin: 0; font-family: system-ui, sans-serif; }
</style>
<link rel="stylesheet" href="/styles/main.css">
<!-- 13. Open Graph -->
<meta property="og:title" content="Page Title">
<meta property="og:description" content="Description under 200 characters.">
<meta property="og:image" content="">
<meta property="og:url" content="https://example.com/current-page">
<meta property="og:type" content="website">
<!-- 14. Twitter Card -->
<meta name="twitter:card" content="summary_large_image">
<!-- 15. Alternate: internationalization or RSS -->
<link rel="alternate" hreflang="fr" href="https://example.fr/">
<link rel="alternate" type="application/rss+xml"
title="RSS Feed" href="/feed.xml">
<!-- 16. Import map (if using ES modules without a bundler) -->
<script type="importmap">
{ "imports": { "lodash": "https://esm.sh/lodash-es" } }
</script>
<!-- 17. Deferred scripts -->
<script src="/js/app.js" defer></script>
</head>
Tags: #html #vdsology #webdevelopment #vdsologyhtml #html5 #htmlreference #htmlreference2026
Write a comment