Semantic HTML5 Elements
Semantic HTML uses meaningful element names that describe the content's purpose. It improves accessibility, SEO, maintainability, and helps screen readers and search engines understand your content.
Document Structure Elements
<body>
<header>
<nav>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
</header>
<main>
<article>
<header>
<h1>Article Title</h1>
<time datetime="2024-01-15">January 15, 2024</time>
<address>By <a href="/author/alice">Alice</a></address>
</header>
<section>
<h2>First Section</h2>
<p>Content...</p>
</section>
<section>
<h2>Second Section</h2>
<figure>
<img src="chart.png" alt="Sales chart showing 30% growth">
<figcaption>Figure 1: Q4 2024 sales growth</figcaption>
</figure>
</section>
<footer>
<p>Tags: <a href="/tag/javascript">JavaScript</a></p>
</footer>
</article>
<aside>
<h2>Related Articles</h2>
<!-- sidebar content -->
</aside>
</main>
<footer>
<p>© 2024 My Site</p>
</footer>
</body>Element Semantics Guide
header: introductory content for a page section or article. Not the same as h1-h6.
nav: major navigation links. Not every group of links needs <nav>.
main: the primary content of the page. Only one per page. Skip link target.
article: self-contained content that would make sense standalone (blog post, product card, comment)
section: thematic grouping of content, typically with a heading. Use div if no heading.
aside: content tangentially related to surrounding content (sidebar, callout box, ads)
footer: footer for its parent section/article (not just the page footer)
figure + figcaption: self-contained content with optional caption (images, code, quotes)
address: contact information for nearest article or body ancestor
time: machine-readable date/time. Always include datetime attribute.
Interactive Elements
<!-- details/summary — native disclosure widget (accordion), no JS needed -->
<details>
<summary>Why should I use semantic HTML?</summary>
<p>Semantic HTML improves accessibility, SEO, and code maintainability...</p>
</details>
<!-- Open by default -->
<details open>
<summary>Default open section</summary>
<p>This is visible by default</p>
</details>
<!-- dialog — native modal dialog -->
<dialog id="my-modal">
<h2>Are you sure?</h2>
<p>This action cannot be undone.</p>
<form method="dialog">
<button value="cancel">Cancel</button>
<button value="confirm">Confirm</button>
</form>
</dialog>
<script>
const dialog = document.getElementById('my-modal');
document.getElementById('open-btn').onclick = () => dialog.showModal();
dialog.addEventListener('close', () => {
console.log('Result:', dialog.returnValue); // 'cancel' or 'confirm'
});
</script>
<!-- mark — highlight text -->
<p>Search results for <mark>typescript</mark> in files.</p>
<!-- abbr — abbreviation with expansion -->
<abbr title="HyperText Markup Language">HTML</abbr>Heading Hierarchy
Only one h1 per page — should match the page title
Don't skip heading levels (h1 → h3 without h2 is wrong)
Headings define document outline — use them for structure, not styling
Use CSS for visual sizing, not lower heading levels
Screen readers navigate pages by heading structure — it matters for accessibility
<!-- Correct heading hierarchy -->
<h1>JavaScript Frameworks</h1>
<h2>React</h2>
<h3>Hooks</h3>
<h3>Context</h3>
<h2>Vue</h2>
<h3>Options API</h3>
<h3>Composition API</h3>
<!-- WRONG — don't use headings just for size -->
<h3>This is not a subsection, I just want smaller text</h3>
<!-- Instead: -->
<p class="subtitle">This is not a subsection</p>Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free