Headings outline the content. Semantic layout elements describe the regions of a page: the site header, the navigation, the main content, sidebars and the footer. Browsers and assistive technology turn these regions into landmarks that people can jump between.
Div soup versus semantic markup
A page built only from div elements gives no clues about its structure:
<div class="header">...</div>
<div class="nav">...</div>
<div class="content">...</div>
<div class="footer">...</div>
The class names help developers, but browsers and screen readers ignore them. The same page with semantic elements:
<header>...</header>
<nav>...</nav>
<main>...</main>
<footer>...</footer>
Now the structure is part of the markup itself. It also makes your HTML easier to read and your CSS selectors shorter.
A complete page layout
<!DOCTYPE html>
<html lang="en-GB">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Baking blog | Riverside Bakery</title>
</head>
<body>
<header>
<a href="/">Riverside Bakery</a>
<nav aria-label="Main">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/blog/">Blog</a></li>
<li><a href="/classes/">Classes</a></li>
</ul>
</nav>
</header>
<main>
<h1>Baking blog</h1>
<article>
<header>
<h2><a href="/blog/rye-starter/">Starting a rye starter</a></h2>
<p>Posted <time datetime="2026-10-02">2 October 2026</time></p>
</header>
<p>A rye starter is faster and more forgiving than one made with white flour.</p>
</article>
<article>
<header>
<h2><a href="/blog/oven-spring/">Getting better oven spring</a></h2>
<p>Posted <time datetime="2026-09-18">18 September 2026</time></p>
</header>
<p>Steam in the first 15 minutes keeps the crust soft long enough for the loaf to rise.</p>
</article>
</main>
<aside aria-label="Upcoming classes">
<h2>Upcoming classes</h2>
<p>Sourdough basics, Saturday 7 November.</p>
</aside>
<footer>
<p>Riverside Bakery, 12 Mill Lane, Bristol</p>
<p><a href="/privacy/">Privacy</a></p>
</footer>
</body>
</html>
The elements
header
header holds introductory content: a logo, a site name, navigation, or the title and date of an article. A page can have several header elements. When it is a direct part of the body, it represents the site header and becomes the banner landmark. Inside an article or section, it is just that section's header and is not a landmark.
nav
nav wraps major blocks of navigation links: the main menu, a table of contents, breadcrumbs or pagination. Not every group of links needs a nav; footer links to legal pages usually do not. When a page has more than one nav, give each a distinct label with aria-label so screen reader users can tell them apart, such as "Main" and "Breadcrumb".
main
main holds the main content of the page: the part that is unique to this page, not the header, navigation and footer repeated on every page.
- Use one visible
mainper page. - Do not put it inside
article,aside,header,footerornav.
main is also the target of "skip to content" links, which let keyboard users jump past the navigation. The Web Accessibility Essentials course shows how to build one.
article
article is a self-contained piece of content that would make sense on its own, for example if syndicated in a feed: a blog post, a news story, a product card, a forum post or a comment. Articles usually have a heading.
section
section groups content on a single theme within a larger whole, such as chapters, or the "Features", "Pricing" and "FAQ" parts of a landing page. A section should normally start with a heading. If you cannot think of a heading for it, it is probably not a section.
aside
aside holds content that is related to the surrounding content but not part of its main flow: a sidebar, a pull quote, related links or a glossary box.
footer
footer holds closing information: copyright, contact details, related links. Like header, the one directly in the body becomes the contentinfo landmark; footers inside articles or sections do not.
Other useful elements
addressgives contact information for the nearestarticleor for the whole page. It is not for any postal address you happen to mention.searchwraps a search form or filtering controls and maps to the search landmark. It is supported in current major browsers, but it is newer than the rest, so check Baseline and remember that older browsers simply treat it like adiv.
Article, section or div?
| If the content… | Use |
|---|---|
| Would make sense on its own, outside this page | article |
| Is a themed part of a larger whole, with its own heading | section |
| Is only there for styling or layout | div |
div is not wrong. It is the right choice when you need a wrapper for CSS, such as a flex container, and the wrapper has no meaning of its own. The goal is to use semantic elements where they apply, not to remove every div.
Articles can contain sections, and sections can contain articles. A blog home page might be a section of article previews; one long article might be split into section elements.
How elements map to landmarks
Assistive technology exposes these regions as landmarks, and screen reader users can list or jump between them.
| Element | Landmark role | Condition |
|---|---|---|
header | banner | When not inside article, aside, main, nav or section |
nav | navigation | Always |
main | main | Always |
aside | complementary | When not inside article, aside, nav or section, or when it has an accessible name |
footer | contentinfo | When not inside article, aside, main, nav or section |
section | region | Only when it has an accessible name, for example from aria-labelledby |
form | form | Only when it has an accessible name |
search | search | Always |
Native elements give you landmarks for free. Adding role="main" to main or role="navigation" to nav repeats what the browser already knows. Keep to the elements; the Web Accessibility Essentials course covers ARIA for the rare cases HTML cannot handle.
Summary
- Use
header,nav,main,asideandfooterfor the regions of a page. - Use
articlefor self-contained content andsectionfor themed parts with a heading. - Keep one visible
mainper page. - Label repeated landmarks such as two
navelements witharia-label. divis still right for wrappers that exist only for styling.