Section 2 · Semantic HTML First
Landmarks and Headings
18 min3 min readCode playground
Lesson at a glance
Turn a page of anonymous divs into landmarks and a logical heading outline that screen reader users can scan and jump through in seconds.
- 1Landmarks: the regions of a page
- 2Naming regions, and how many to use
- 3Headings: the outline people navigate
No video here — just the real thing: a written lesson, runnable examples, a quiz and practice.
Samir once described a badly built page to me as “a phone book with the names torn off”. Everything is there, but nothing tells him where one part ends and the next begins. Ticketly’s home page is exactly that: every block is a div, and the biggest text is a div with a large font. A sighted user sees a header, a menu, a festival title, a line-up and a footer. A screen reader sees one long stream of text.
Landmarks: the regions of a page
HTML has elements that describe the role of a whole region. The browser maps each to an ARIA landmark, and screen readers let users list landmarks or jump between them (the D key in NVDA, the rotor in VoiceOver).
| Element | Landmark role | Notes |
|---|---|---|
<header> |
banner | Only when it is a direct part of the page, not inside article, aside, main, nav or section |
<nav> |
navigation | Name it when there are several |
<main> |
main | Exactly one visible per page |
<aside> |
complementary | Related content such as a sidebar |
<footer> |
contentinfo | Same scoping rule as header |
<form>, <section> |
form, region | Only when they have an accessible name |
<search> |
search | Wraps a site search form |
Here is Ticketly’s skeleton before and after:
<div class="top">
<div class="logo">Ticketly</div>
<div class="links"><a href="/events">Events</a> <a href="/faq">FAQ</a></div>
</div>
<div class="content">
<div class="title">Harbour Lights 2026</div>
…
</div>
<div class="bottom">© 2026 Ticketly · <a href="/terms">Terms</a></div><header>
<a href="/" class="logo">Ticketly</a>
<nav aria-label="Site">
<a href="/events">Events</a> <a href="/faq">FAQ</a>
</nav>
</header>
<main>
<h1>Harbour Lights 2026</h1>
…
</main>
<footer>© 2026 Ticketly · <a href="/terms">Terms</a></footer>The visual design doesn’t change at all; these elements have no special styling beyond display: block. What changes is the accessibility tree: Samir can now press D to land on “main landmark” and start reading the festival content, skipping the header entirely.
Naming regions, and how many to use
A <section> on its own is just a generic container. Give it a name and it becomes a region landmark that appears in the landmarks list. The neatest way is to point at its own heading, so the name and the visible text can never drift apart:
<section aria-labelledby="tickets-heading">
<h2 id="tickets-heading">Tickets</h2>
…
</section>Don’t turn every section into a region, though. Landmarks work like the chapter list of a book: five to eight entries are useful, thirty are not. The rule of thumb is that every piece of content lives inside some landmark (automated checkers flag text that doesn’t), and that only the big, distinct areas a user might want to jump to get one of their own.
Headings: the outline people navigate
Landmarks are the rooms of the page; headings are the signs on the doors. Most screen reader users find content by jumping from heading to heading (H in NVDA and JAWS, or 1 to 6 for a specific level), or by opening a list of all headings and typing to filter it. That list is only useful if the headings form a real outline.
Three rules cover almost every case:
- One
h1that says what the page is. On Ticketly, “Harbour Lights 2026”, not the logo. - Levels describe nesting. A section’s subsections are one level deeper. Going back up is fine (h3 to h2); skipping down (h2 to h4) suggests a missing level.
- Every heading has content under it, and every chunk of content worth finding has a heading.
Ticketly’s tickets area uses h4 and h5 because a designer wanted smaller text. Fix the structure first, then style:
<h2>Tickets</h2>
<h3 class="pass-title">Friday pass</h3>
<h3 class="pass-title">Weekend pass</h3>.pass-title {
font-size: 1rem;
font-weight: 600;
}Don’t forget the page’s <title> either. It is the first thing a screen reader announces when the page loads and what appears in tabs and history (2.4.2 Page Titled). Put the specific part first: <title>Harbour Lights 2026 tickets · Ticketly</title>.
With the skeleton in place, the next lesson tackles the parts users actually click: buttons, links, and the clickable divs pretending to be both.
Key takeaways
- The elements header, nav, main, aside and footer create landmarks that screen reader users can list and jump between.
- A page has one main landmark; when there are several nav or aside regions, give each a distinct accessible name.
- Headings form the page’s outline; choose the level for structure, never for font size, and style the size with CSS.
- Start with one h1 that names the page, and don’t skip levels on the way down.