Nav, Main & Aside
<nav> for navigation link sets, <main> for the page's unique primary content, and <aside> for tangentially related supplementary material. Each solves a specific accessibility and structural problem that a plain <div> cannot.
nav — Navigation Links
<nav> marks a block of navigation links. It should wrap your main site menu, breadcrumbs, and in-page table of contents — but not every group of links. A list of "Related articles" at the bottom of a blog post doesn't warrant a <nav>; those belong in <aside> or just in the article footer.
<!-- Skip link — first focusable element on the page --> <a href="#main-content" class="skip-link"> Skip to main content </a> <header> <nav aria-label="Main navigation"> <ul role="list"> <li><a href="/" aria-current="page">Home</a></li> <li><a href="/courses">Courses</a></li> <li><a href="/blog">Blog</a></li> </ul> </nav> </header> /* CSS for skip link */ .skip-link { position: absolute; top: -40px; /* hidden off-screen */ left: 0; } .skip-link:focus { top: 0; /* visible on keyboard focus */ }
aria-current="page" marks the active nav link — screen readers announce "current page" when the user focuses it, so they know where they are.
main — Primary Content
<main> wraps the content that is unique to this page — not the repeated navigation, header, or footer. There must be only one <main> per page. It gets ARIA role main, which screen reader users can jump to directly.
<body> <header>...</header> <nav>...</nav> <!-- The id matches the skip link's href --> <main id="main-content"> <!-- Unique page content only --> <h1>Page Title</h1> <article>...</article> </main> <footer>...</footer> </body>
| Rule | Why |
|---|---|
| Only one <main> per page | ARIA spec: multiple mains confuse screen reader landmark navigation |
| Don't nest <main> in <header> or <footer> | main is always a sibling of these, never a child |
| Add id="main-content" to pair with skip link | The skip link's href="#main-content" jumps focus here |
| No repeated content inside main | Navigation, search bars, and ads go outside main |
aside — Supplementary Content
<aside> holds content that is related to, but not essential to, the surrounding content. Removing it wouldn't break the article. Common uses: sidebars, pull quotes, author bios, related posts, ads, and "Did you know?" call-outs.
<main> <article> <h1>CSS Grid Layout Guide</h1> <p>Main article content...</p> </article> <aside aria-label="Related content"> <h2>Related Lessons</h2> <ul> <li><a href="/css-flexbox">CSS Flexbox</a></li> <li><a href="/css-variables">CSS Variables</a></li> </ul> </aside> </main>
<article> <p>The performance improvements were significant...</p> <aside> <blockquote> "We reduced load time by 60% just by switching to CSS Grid for the main layout." </blockquote> </aside> <p>The team began migrating in early 2024...</p> </article>
<aside> just because you want something visually off to one side. The element carries semantic meaning: "this content is tangentially related." A sidebar ad, a related articles list, or an author bio box — yes. A decorative image column that visually floats right — no, that's a CSS layout decision.nav vs aside for Link Lists
The distinction between <nav> and <aside> for link lists is important:
| Scenario | Use | Why |
|---|---|---|
| Main site menu | <nav> | Primary way to navigate the site |
| Breadcrumb trail | <nav> | Navigation aid for the current location |
| Pagination (prev/next) | <nav> | Navigation between pages of content |
| Table of contents | <nav> | In-page navigation landmark |
| Related articles list | <aside> | Supplementary — not primary navigation |
| Tag cloud | <aside> | Tangentially related, not navigation |
| Social share buttons | Neither — use a <div> | Not navigation, not supplementary content |
Structure requirements:
- A skip link as the first element, targeting #main-content
- A <header> with a nav (aria-label="Main navigation") containing 4 links; the current page link has aria-current="page"
- A <main id="main-content"> containing an <article> with header, h1, and some paragraphs
- An <aside aria-label="Sidebar"> inside main (next to the article) with a "Related Posts" list and a "Tags" section
- A <nav aria-label="Article navigation"> with prev/next article links inside main (below the article)
- A page <footer> with copyright
CSS: lay out main as a 2-column grid (article takes 2/3, aside takes 1/3). Make the skip link visible on focus.
Show hints
- Skip link CSS: position:absolute; top:-100%; left:0 — then :focus { top:0 }
- main { display: grid; grid-template-columns: 2fr 1fr; gap: 2rem; }
- The article nav (prev/next) can span full width: grid-column: 1 / -1
- The aside's Related Posts is NOT a <nav> — it's supplementary, not primary navigation