What is semantic HTML?
Semantic HTML means choosing elements that describe what content is, not how it looks. A <nav> is a block of navigation. An <article> is self-contained content. A <button> performs an action. These elements carry meaning that browsers, assistive technology and search engines can act on.
The alternative is a page built from generic <div> and <span> elements, often called “div soup”. It can look identical on screen while being opaque to a screen reader and harder to maintain. Semantics cost nothing and pay off everywhere.
Landmarks
Landmark elements define the major regions of a page and let users jump between them.
<!-- layout.html -->
<body>
<header>
<a href="/">hackweb</a>
<nav aria-label="Main">
<a href="/guides">Guides</a>
</nav>
</header>
<main>
<h1>Guides</h1>
</main>
<footer>
<p>© 2026 hackweb.dev</p>
</footer>
</body>
- header — introductory content for the page or a section.
- nav — a block of navigation links. Label repeated navs with
aria-label. - main — the primary content, used once and skipped to by screen readers.
- aside — content tangentially related to the main content.
- footer — closing content such as copyright or related links.
Screen reader users can list and jump between landmarks, which turns a long page into a navigable structure.
Headings
Headings form the outline of the page. Use a single <h1> for the main topic, then <h2> and <h3> for sections and subsections.
<!-- outline.html -->
<h1>CSS Grid</h1>
<h2>Tracks and lines</h2>
<h3>Defining columns</h3>
<h3>Placing items</h3>
<h2>Responsive grids</h2>
Never pick a heading level for its size. Use CSS for appearance and headings for structure. Skipping levels, such as jumping from h1 to h4, makes the outline confusing for assistive technology.
Content elements
Beyond landmarks, HTML has elements for specific kinds of content.
- article — self-contained content that could stand alone, like a post or comment.
- section — a thematic group, usually with a heading.
- figure and figcaption — media with a caption.
- blockquote and cite — a quotation and its source.
- time — a date or time with a machine-readable
datetime. - address — contact information.
- ul, ol, dl — unordered, ordered and description lists.
<!-- post.html -->
<article>
<h1>What is DNS?</h1>
<p><time datetime="2026-09-15">September 15, 2026</time></p>
<figure>
<img src="/dns.svg" alt="A DNS lookup walks the name hierarchy" width="800" height="400" />
<figcaption>Resolving a name step by step.</figcaption>
</figure>
<blockquote cite="https://example.com">
<p>DNS is the internet's phone book.</p>
</blockquote>
</article>
Using the right element means you get the right default behaviour and the right meaning, with no extra work.
Links versus buttons
This is the most common semantic mistake.
- Use
<a href>for navigation to a URL. It supports right-click, open in a new tab, bookmarking and keyboard activation. - Use
<button>for actions that change state or submit data. It is focusable, keyboard-operable and announced as a button.
<!-- controls.html -->
<a href="/guides/css">Read the CSS guide</a>
<button type="button" onclick="toggleMenu()">Toggle menu</button>
A <div onclick="..."> looks clickable but is not reachable by keyboard, not announced as a control and not focusable. Fixing it requires recreating everything the button gives you for free.
Forms and tables
Forms have their own semantics: <form>, <label>, <fieldset>, <legend>, <input>, <select> and <textarea>. Every input should have a label, and grouping related controls with fieldset and legend helps everyone. The Forms & Validation guide goes deeper.
Tables are for tabular data, not layout. Use <table>, <thead>, <tbody>, <th> with scope and <caption> so the relationship between cells and headers is clear.
When a div is fine
Generic elements are not a sin. Use <div> and <span> when you genuinely need a container for styling or layout with no semantic meaning. The rule is simple: reach for a semantic element when one exists, and use a div when none fits. Adding section without a heading or nav around a single unrelated link adds noise rather than meaning.
Best practices
- Use one
h1and keep heading levels in order. - Structure pages with header, nav, main and footer.
- Use article and section for content, not div.
- Prefer button for actions and anchors for navigation.
- Give every image meaningful
alttext, oralt=""if decorative. - Label form controls and group related ones.
- Validate your HTML so the parser does not have to recover.
Common mistakes
- Building everything from divs and spans.
- Using a div with an onclick instead of a button.
- Choosing heading levels by font size.
- Multiple h1 elements with no clear main topic.
- Using tables for layout.
- Wrapping single links in a nav, or using section without a heading.
Where to go next
Semantics are the foundation of an accessible, findable page. Build on HTML basics, make it inclusive with the Accessibility guide, support it with SEO Basics, and complete the picture with Forms & Validation.