Structure a page with meaning using div, span, header, footer, nav, main, section, article, and aside. Semantic elements improve accessibility and SEO.
When: reach for <div> and <span> only after checking whether a semantic element fits — <section>, <article>, <nav>, etc. Why: they carry no meaning, so overusing them makes your HTML harder for assistive technologies to navigate. <div> for block-level grouping, <span> for inline styling hooks.
<!-- <div> — generic block container -->
<div class="card">
<h2>Title</h2>
<p>Content here.</p>
</div>
<!-- <span> — generic inline container -->
<p>Price: <span class="price">$29.99</span></p>Where: both can appear more than once — once at the page level and again inside each <article> or <section>. Why: they tell assistive technologies what role that content plays — intro/logo/nav for <header>, copyright/secondary links for <footer>.
<header>
<a href="/">My Site</a>
<nav>...</nav>
</header>
<footer>
<p>© 2025 My Site. All rights reserved.</p>
</footer>Why: <nav> is a landmark — screen reader users can jump directly to it without tabbing through everything above. When to add aria-label: if you have more than one <nav> on a page (e.g. main nav and breadcrumbs), label each so users can tell them apart.
aria-label — Names this navigation region. Required when there is more than one <nav> on the page so screen readers can distinguish them (e.g. "Main navigation", "Breadcrumbs").<nav aria-label="Main navigation">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>Why: screen reader users can skip directly to <main>, bypassing the header and nav they have already heard. Where: one per page, at the root of <body> — never nested inside <header>, <footer>, or <nav>.
<!-- Only one <main> per page -->
<body>
<header>...</header>
<main>
<h1>Welcome</h1>
<p>This is the main content.</p>
</main>
<footer>...</footer>
</body>When <article>: if the content makes sense on its own when extracted — a blog post, product card, comment, or news item. When <section>: grouping related content within a page — always pair it with a heading. Why: both carry semantic meaning that helps screen readers and search engines understand the document structure.
<!-- <article> — self-contained content (blog post, comment, card) -->
<article>
<h2>Post Title</h2>
<p>Published on <time datetime="2025-01-01">Jan 1, 2025</time></p>
<p>Body of the post...</p>
</article>
<!-- <section> — thematic grouping within a page -->
<section>
<h2>Features</h2>
<p>Feature descriptions...</p>
</section>When: sidebars, pull quotes, callout boxes, related links — content that adds context but is not part of the main flow. Where: inside an <article> it refers to that article's author or topic; inside <main> it relates to the whole page.
<main>
<article>
<h2>Main Article</h2>
<p>Article content...</p>
</article>
<aside>
<h3>Related Links</h3>
<ul>
<li><a href="/related-1">Related Article 1</a></li>
<li><a href="/related-2">Related Article 2</a></li>
</ul>
</aside>
</main>