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 <head>. Doesn’t appear in the rendered page directly, but describes the page and its relationship to other resources.

<meta name="viewport" content="width=device-width,initial-scale=1.0">

Flow

Text and (almost) all elements that can appear as content in the <body>.

<body><h1>Heading</h1><p>Some content…​</p></body>

Sectioning

Structures the content of a page and defines the scope of headings and footers within it (header, footer, nav, article, aside, section).

<article><section>…​</section></article>

Phrasing

Elements used to mark up text within a paragraph-level element (e.g. em, strong, span).

<p><em>Emphasized text</em> and some normal text.</p>

Heading

Defines the headings of a section, h1-h6, with h1 ranking highest.

<h1>Main Heading</h1><h2>Subheading</h2>

Embedded

Media content: images, audio, video, and similar.

<img src="media/kitten.png" alt="A cute kitten">

Interactive

Elements the user can directly interact with: form controls, buttons, links, and media with controls.

<input type="password" name="password" required>

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

base

Sets a base URL that every relative URL in the document resolves against. At most one per document.

href, target

link

Declares a relationship between the page and an external resource, most commonly a stylesheet or a favicon.

rel, href, type

meta

A catch-all for metadata that doesn’t have a dedicated element — character encoding, viewport behavior, page description, social-preview tags, and more.

name/content, charset, http-equiv

title

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>

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.

flowchart TD HTML["<html lang="en">"] --> HEAD["<head>"] HTML --> BODY["<body>"] HEAD --> META["title, meta, link, base"] BODY --> HEADER["<header>"] BODY --> MAIN["<main>"] BODY --> FOOTER["<footer>"] HEADER --> NAV["<nav>"] MAIN --> ARTICLE["<article>"] MAIN --> SECTION["<section>"] MAIN --> ASIDE["<aside>"]

Reference: metadata and semantic structural elements

Element Typical attributes Example

base

href, target

<base href="https://example.com/" target="_blank">

link

rel, href, type

<link rel="stylesheet" href="/css/site.css">

meta

charset; name/content; http-equiv

<meta name="viewport" content="width=device-width, initial-scale=1.0">

title

(none)

<title>Page Title</title>

header

(global attributes only, e.g. class, id)

<header><h1>Site Name</h1></header>

footer

(global attributes only)

<footer>© 2026 Example Inc.</footer>

nav

aria-label (to distinguish multiple nav elements for screen readers)

<nav aria-label="Primary"><a href="/">Home</a></nav>

main

(global attributes only; at most one visible per page)

<main><article>…​</article></main>

article

(global attributes only)

<article><h2>Post title</h2><p>Body…​</p></article>

section

(global attributes only; usually contains its own heading)

<section><h2>Related products</h2>…​</section>

aside

(global attributes only)

<aside>Related links go here.</aside>

div

class, id (its only means of carrying meaning, since it has none of its own)

<div class="navigation">…​</div>

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

<!DOCTYPE html> as the first line of the document; case-insensitive; HTML5 has a single, simple form.

<html lang="">

The document root; always set lang for accessibility, screen readers, and translation tools.

<head> vs <body>

<head> is machine-read metadata not rendered directly; <body> is the content rendered for the reader.

Metadata elements

base (base URL), link (external resource relationships), meta (catch-all, including viewport and charset), title (page name).

Semantic structural elements

header, footer, nav, main, article, section, aside replace the pre-HTML5 pattern of a div with a descriptive class, giving the browser, screen readers, and search engines real semantic meaning instead of a class-name convention.