HTML5 Structure and Semantics
|
This section documents general HTML5 and CSS concepts — it is not tied to any specific framework or library. This content was generated with the assistance of AI. Verify it against current MDN documentation and browser-support tables (caniuse.com) before relying on it in production, since HTML/CSS features and browser support continue to evolve. |
Every HTML document is a tree of elements rooted at <html>, split into a <head> (machine-read metadata)
and a <body> (the content rendered for a human reader). HTML5 groups its hundred-plus elements into a
handful of content types that describe where an element is allowed to appear, and it adds a set of
semantic elements — header, footer, nav, main, article, section, and aside — that give
structural meaning to areas of a page that developers previously had to mark up with a generic div and a
class name. This page covers both: the content-type taxonomy and document skeleton, and the semantic
elements used to build that skeleton. Search-engine- and crawler-facing metadata is covered separately in
SEO Implications of HTML Structure.
HTML5 content types
Rather than memorizing what each of HTML5’s elements does individually, it helps to think in terms of the content type(s) an element belongs to — this determines where it is valid to place it in a document. Many elements belong to more than one category.
| Content type | Description | Example |
|---|---|---|
Metadata |
Content hosted in the |
|
Flow |
Text and (almost) all elements that can appear as content in the |
|
Sectioning |
Structures the content of a page and defines the scope of headings and footers within it ( |
|
Phrasing |
Elements used to mark up text within a paragraph-level element (e.g. |
|
Heading |
Defines the headings of a section, |
|
Embedded |
Media content: images, audio, video, and similar. |
|
Interactive |
Elements the user can directly interact with: form controls, buttons, links, and media with controls. |
|
An element can straddle several categories at once. A good example is <img>: it is embedded
content because it embeds an image, flow content because it can appear directly in the body, and
phrasing content because it can appear inline within a paragraph — but it only becomes interactive
content when given a usemap attribute that turns regions of the image into an image map of hyperlinks.
An <img> is never metadata, sectioning, or heading content.
Document structure
Doctype and the root <html> element
An HTML5 document begins with a doctype declaration, <!DOCTYPE html>, which tells the browser it is
dealing with an HTML5 document. HTML5 simplified this considerably: earlier HTML4/XHTML1 doctypes were
long, versioned strings (e.g. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">), whereas HTML5 has a single, case-insensitive doctype
(<!doctype html> and <!DOCTYPE HTML> are equally valid).
After the doctype comes the root <html> element. It should always carry a lang attribute (e.g.
lang="en") so browsers, screen readers, and translation tools know what language the page’s text content
is in.
<!doctype html>
<html lang="en">
<head><title>Page Title</title></head>
<body></body>
</html>
The head/body split
The <html> root has exactly two children:
-
<head>— metadata: the page title and information about assets to load, and hints for how web crawlers and search engines should handle the page. Nothing in<head>is rendered directly on the page. -
<body>— the content rendered for a human reader: headings, paragraphs, images, navigation, and so on.
Elements at the same level of the tree (e.g. <head> and <body>) are siblings; an element inside
another is its child (and, transitively, its descendant); the containing element is that child’s
parent (and ancestor).
Metadata elements
The following elements are metadata content and are only valid inside <head>:
| Element | Purpose | Typical attributes |
|---|---|---|
|
Sets a base URL that every relative URL in the document resolves against. At most one per document. |
|
|
Declares a relationship between the page and an external resource, most commonly a stylesheet or a favicon. |
|
|
A catch-all for metadata that doesn’t have a dedicated element — character encoding, viewport behavior, page description, social-preview tags, and more. |
|
|
The name of the page, shown in the browser tab and search results, and announced by screen readers. Exactly one per document. |
(none — text content only) |
<head>
<!-- character encoding should be declared first, and as early as possible in <head> -->
<meta charset="UTF-8">
<!-- makes the page render at device width instead of a desktop-width viewport scaled down -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Page Title</title>
<base href="https://example.com/">
<link rel="stylesheet" href="/css/site.css">
<link rel="icon" href="/favicon.ico">
</head>
The viewport meta tag is what makes a page responsive on mobile devices: without it, mobile browsers
render the page at a desktop-sized viewport (typically 980px wide) and then zoom it out, which defeats any
responsive CSS. width=device-width ties the viewport to the device’s own width, and initial-scale=1.0
sets the initial zoom level to 1:1.
Semantic structural elements
Prior to HTML5, developers divided a page into areas — a header, a footer, a navigation block, a sidebar — using a generic <div> with a class naming the area’s purpose (e.g. class="header"). The browser,
screen readers, and search engines had no way to tell that div apart from any other; the only signal was
the class name, which is invisible to machines. HTML5 adds dedicated elements for each of these common
areas, giving them real semantic meaning instead of a class-name convention.
header
The header element marks the top area of a page (or of a section/article): typically a heading, a
logo, and/or navigation.
<!-- old way -->
<div class="header">
... heading, logo, nav goes here
</div>
<!-- new way -->
<header>
... heading, logo, nav goes here
</header>
footer
The footer element marks the bottom area of a page (or of a section/article): typically copyright
information and a list of links.
<!-- old way -->
<div class="footer">
... copyright, list of links go here
</div>
<!-- new way -->
<footer>
... copyright, list of links go here
</footer>
nav
The nav element wraps a block of navigation links — the page’s primary navigation, a table of contents,
or similar.
<!-- old way -->
<div class="navigation">
... list of links go here
</div>
<!-- new way -->
<nav>
... list of links go here
</nav>
main
The main element wraps the page’s primary, unique content — the content that is specific to this page,
as opposed to content (navigation, branding, site-wide search) repeated across every page of the site.
There should be exactly one visible main per page, and it should not be nested inside header, footer,
nav, article, or aside.
<main>
<article>...</article>
</main>
article
The article element marks a self-contained piece of content that would make sense distributed or
reused on its own — a blog post, a news story, a forum post. Multiple article elements can appear on
one page, and each must stand independently of the page’s other context. It is common to divide an
article into section elements:
<article>
<section>
...primary blog content
</section>
<section>
...secondary blog content
</section>
</article>
section
The section element groups a thematically related chunk of content — a page’s main content area, or a
group of related items — without necessarily being a self-contained, reusable unit the way article is.
<!-- old way -->
<div class="main-content-section">
... main content
</div>
<!-- new way -->
<section>
... main content
</section>
aside
The aside element marks content that is only indirectly related to the surrounding main content — sidebars, pull quotes, or notes.
<!-- old way -->
<div class="sidebar">
... indirectly related content goes here
</div>
<!-- new way -->
<aside>
... indirectly related content goes here
</aside>
div
div (short for "division") remains the generic, semantically-neutral element used purely to group
markup for styling or scripting purposes — it is still the most common element on the web, since HTML5’s
semantic elements only cover the handful of areas common to most pages. Reach for a semantic element first;
fall back to div (with a class or id) whenever no semantic element fits the grouping you need.
<div class="navigation">
<div class="navigation-inner">
... navigation links go here
</div>
</div>
Semantic page skeleton
Putting the elements above together, a typical semantic HTML5 skeleton nests as follows: the root
<html> splits into <head> and <body>; the <body> splits into <header>, <main>, and <footer>;
and <main> contains the page’s <article>/<section>/<aside> content blocks.
Reference: metadata and semantic structural elements
| Element | Typical attributes | Example |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
(none) |
|
|
(global attributes only, e.g. |
|
|
(global attributes only) |
|
|
|
|
|
(global attributes only; at most one visible per page) |
|
|
(global attributes only) |
|
|
(global attributes only; usually contains its own heading) |
|
|
(global attributes only) |
|
|
|
|
Summary
| Concept | Key point |
|---|---|
Content types |
Metadata, flow, sectioning, phrasing, heading, embedded, and interactive content describe where an element is valid to place — many elements belong to more than one type. |
Doctype |
|
|
The document root; always set |
|
|
Metadata elements |
|
Semantic structural elements |
|