Cheat Sheet
HTML5 Semantic Tags
A quick reference for semantic HTML elements: what they mean, when to use them, and how to keep your document outline clean, accessible, and search-engine friendly.
Semantic markup exists so the meaning of content survives presentation. Assistive technology such as screen readers navigates by element role, so a heading announces as a heading only when it is actually an h1 through h6 element. Search engines use the same structure to infer what a page covers and which parts matter. The third reader is the maintainer, because a document built from nav, article and aside stays legible months later, while a nest of plain divs does not. The WHATWG HTML standard defines each element, its content model, and the contexts where it is allowed, which makes it the reference for every entry on this sheet.
Pick the element that names the role, and reach for div only when nothing else fits.
Document outline
Sectioning elements plus your heading levels form the document outline. A well-formed page nests <main> inside <body>, keeps a single <h1>, and groups related content with <section> and <article>.
The document outline is the heading tree that user agents and assistive tools can extract from a page. Sectioning elements such as article, section, aside and nav each open a new outline section, and h1 through h6 rank the content inside it. A document works best when its outline reads like a table of contents, with one top-level heading and a sensible depth at every branch. The semantics chapter of the HTML standard explains how sectioning elements and headings combine into this tree, and it is also where the rules for a single main element and one h1 per page come from.
A few outline mistakes cause most of the confusion in real pages. Skipping levels, such as moving from h2 to h5 because a design needs smaller type, breaks the announced order for screen reader users even when the page looks fine. Filling every region with div adds nothing to the outline, so assistive tools must guess at the relationships between blocks. Headings nested inside a component without a sectioning element flatten the tree instead of building it. The correction is almost always structural. Give each section a real heading, and keep heading levels for meaning rather than for font size.
<body>Every page<header>Site header: logo, title, tagline<nav>Primary navigation links<main>Unique page content (exactly one per page)<article>Self-contained piece: blog post, card, comment<section>Intro / overview<section>Details / body<aside>Related links, sidebar, pull quote<footer>Site footer: copyright, contact, legalDocument Structure
Elements that define the skeleton of a page. They tell assistive tech and search engines how the layout is organized.
Choosing between article, section and div is the most frequent judgment call in semantic markup. Use article for content that stands alone and could be redistributed, such as a blog post, a news item or a product card. Use section for a thematic group inside a larger document, and give it a heading so its purpose is announced. Use div only when no named element fits. The standard also requires main to be unique and to stay outside other sectioning content, and it reserves nav for groups of major navigation links rather than for every list of links that appears on a page.
aside, footer and header have narrower jobs than their names suggest. aside holds content that is tangentially related to the surrounding flow, such as a sidebar or a set of related links, and it is not a synonym for any right-hand column. footer carries closing information for its nearest sectioning root, so a footer inside an article covers that article and not the whole page. header introduces the nearest sectioning content or root, which is why a repeated site header and a per-article header can both use the same element. Matching the element to its scope removes the ambiguity that generic wrappers create.
Would this block still make sense on its own? If yes, article is the safer choice.
headerIntroductory content for the page or a section: logo, site title, tagline, or a group of navigational links.
<header>
<h1>My Blog</h1>
<nav>…</nav>
</header>navA block of major navigation links. Use it for primary or secondary nav, not for every list of links on the page.
<nav aria-label="Primary">
<a href="/">Home</a>
<a href="/about">About</a>
</nav>mainThe dominant, unique content of the document. Exactly one per page, and it must not be nested inside another sectioning element.
<main>
<article>…</article>
</main>articleA self-contained composition that could stand alone and be redistributed: a blog post, news item, product card, or comment.
<article>
<h2>Post title</h2>
<p>The content…</p>
</article>sectionA thematic grouping of content, typically with its own heading. Use it when no more specific element applies.
<section>
<h2>Features</h2>
<ul>…</ul>
</section>asideContent that is tangentially related to the surrounding content: a sidebar, related links, or a pull quote.
<aside>
<h3>Related</h3>
<a href="/similar">See also</a>
</aside>footerClosing information for its nearest sectioning root: author, copyright, related links, or legal notices.
<footer>
<p>© 2026 DevDesignKit</p>
</footer>Content Semantics
Elements that give text meaning (quotations, code, dates, abbreviations, and emphasis) so content is machine-readable, not just styled.
Content-level elements exist so that meaning stays readable by machines as well as by people. time with a datetime attribute exposes an unambiguous instant whatever the displayed format. abbr with a title attribute expands an acronym for assistive technology and for readers who need it. mark flags text that is relevant to the current task, such as a search match, rather than serving as a generic highlighter. Each of these elements has a precise content model in the standard, and the machine-readable meaning is the reason they exist instead of plain styled spans.
Most content-level mistakes come from styling habits. Using blockquote for indentation is a classic misuse, because blockquote marks a quotation from another source and nothing else. code without pre loses whitespace in multiline blocks, while pre without code carries no semantic value at all. address is not a generic postal address element, it names contact information for the nearest article or for the page author. figure pairs a self-contained illustration with its caption when the two should travel together. Reading the content model of each element in the standard resolves these cases faster than guessing from rendered appearance.
If the markup does not name the content, a screen reader cannot either.
h1 – h6Six heading levels that build the document outline. Never skip levels, and use headings for structure, not for font sizing.
<h1>Page title</h1>
<h2>Section</h2>
<h3>Subsection</h3>pA paragraph of prose. Block-level by default; use it for running text rather than line breaks.
<p>This is a paragraph of text.</p>blockquoteA longer quotation from another source. Use the cite attribute to reference the source URL.
<blockquote cite="https://example.com">
<p>Words worth quoting.</p>
</blockquote>codeAn inline fragment of computer code. Pair with pre for multi-line blocks.
<p>Call <code>Array.map()</code> to transform.</p>prePreformatted text that preserves whitespace and line breaks: the go-to wrapper for code blocks and ASCII art.
<pre><code>const x = 42;</code></pre>figureSelf-contained content (an image, diagram, chart, or code listing) that is referenced from the main flow and can be moved without breaking meaning.
<figure>
<img src="chart.png" alt="Trend chart">
</figure>figcaptionA caption for the content inside a figure. Must be a child of figure, first or last.
<figure>
<img src="chart.png" alt="Trend">
<figcaption>Fig. 1: Growth</figcaption>
</figure>timeA machine-readable date or time via the datetime attribute, so tools can parse it regardless of the human display format.
<time datetime="2026-09-10">Sep 10, 2026</time>markText highlighted for its relevance in the current context (e.g. a search match): not a generic highlighter.
<p>…the <mark>query</mark> matched…</p>abbrAn abbreviation or acronym. The title attribute provides the full expansion shown on hover.
<abbr title="HyperText Markup Language">HTML</abbr>addressContact information for the author or owner of the nearest article or body: not a generic postal address.
<address>
<a href="mailto:hi@example.com">hi@example.com</a>
</address>Interactive & Media
Elements for native disclosure, dialogs, and rich media embedding: no JavaScript plugins required.
Native interaction elements remove whole classes of script. details with a summary child gives a disclosure widget without any JavaScript, which makes it the progressive enhancement default for collapsible sections. dialog adds native modal handling through showModal(), including focus management and the Escape key behavior described in the standard. Both elements keep keyboard behavior and role announcements for free, where a scripted imitation must rebuild them by hand. When a platform element fits the job, its standard contract is easier to maintain than a custom implementation.
Media elements pair with fallbacks so that content never depends on one format. video and audio can carry multiple source children, and the browser selects the first supported type. picture lets authors offer art direction, format or resolution variants, and it must always end in an img element as the final fallback. canvas displays its fallback text when canvas support is missing, and that content doubles as a place to describe the drawing for screen readers. These fallback layers are part of the standard contract for each element, and respecting them keeps media accessible across browsers.
Every media element should be able to fail gracefully, not silently.
detailsA disclosure widget users can open and close to reveal additional information, without writing any JS.
<details>
<summary>More info</summary>
<p>Hidden until opened.</p>
</details>summaryThe visible heading or trigger for a details element. It must be the first child of details.
<details>
<summary>How does it work?</summary>
…
</details>dialogA modal or non-modal dialog box. Open it as a modal with showModal(); the open attribute makes it non-modal.
<dialog id="confirm">
<p>Are you sure?</p>
</dialog>videoEmbeds a video with native controls. Add source children for multiple formats, plus a text fallback.
<video controls width="640">
<source src="movie.mp4" type="video/mp4">
</video>audioEmbeds an audio clip with native playback controls.
<audio controls>
<source src="song.mp3" type="audio/mpeg">
</audio>canvasA scriptable drawing surface for 2D graphics or WebGL. Content inside it is fallback for unsupported browsers.
<canvas width="400" height="300">
Fallback text
</canvas>pictureA responsive image container: browser picks the best matching source (art direction, format, or resolution) before falling back to img.
<picture>
<source srcset="hero.webp" type="image/webp">
<img src="hero.jpg" alt="Hero">
</picture>The HTML Living Standard and WCAG references behind this cheat sheet
Each entry below backs one or more claims made on this page.
- WHATWG, HTML Living Standard: Semantics Defines every semantic element on this sheet, including content models, allowed nesting, and the sectioning rules behind the document outline at the top.
- WHATWG, HTML Living Standard: DOM The basis for the outline and heading statements here, specifying element categories, hierarchical structure and heading behavior in the DOM tree.
- W3C, WCAG 2.2 The accessibility standard behind the advice that semantic structure helps assistive technology, in particular the Info and Relationships success criterion.
- W3C, WCAG 2.2 Quick Reference A filterable view of the same criteria, useful for checking headings, landmarks and media fallbacks against requirement 1.3.1 and related ones.