Skip to main content

Semantic HTML

Semantic HTML uses tags that describe the meaning of content (<article>, <nav>, <main>) instead of generic containers (<div>, <span>), so browsers, screen readers, and search engines understand what each part of the page actually is.

Theory

TL;DR

  • <header> says 'this IS the header'; <div class="header"> just says 'looks like one'
  • Semantic tags automatically expose ARIA roles to assistive tech - no extra attributes needed
  • <nav> becomes 'navigation landmark', <main> becomes 'main landmark' without any JavaScript
  • Use semantic tags for content structure; fall back to <div> only for styling or JS containers

Quick example

html
<!-- Non-semantic: screen reader sees "Div. Div. Div." --> <div class="header">Logo & Nav</div> <div class="main-content">Article body</div> <div class="footer">Copyright</div> <!-- Semantic: screen reader announces "Banner region. Navigation. Main." --> <header> <img src="logo.png" alt="Company logo"> <nav><!-- navigation links --></nav> </header> <main> <article>Article content</article> </main> <footer>© 2026 Company</footer>

Same visual output. Completely different meaning for everything that reads the HTML.

Key difference

<div class="nav"> and <nav> look identical in a browser. But <nav> automatically maps to role="navigation" in the accessibility tree during DOM construction. A screen reader user can jump straight to it. With <div>, you have to add role="navigation" manually - and that attribute gets removed during refactors, consistently.

When to use

  • Page has a site header, navigation, main content, and footer - use <header>, <nav>, <main>, <footer>
  • Writing a blog post or news article - wrap it in <article>, use <section> for thematic chunks that have headings
  • Building a sidebar with related links - <aside>
  • Creating a layout grid or JS-controlled container with no inherent meaning - <div> is fine

How browsers handle this

During HTML parsing, Blink (Chrome) and Gecko (Firefox) map semantic elements directly to the accessibility tree. <header> at the top level gets role="banner" automatically. <main> gets role="main". Screen readers query this tree via platform APIs (MSAA on Windows, AXAPI on macOS) without any JavaScript. This happens at parse time, not after scripts run.

Common mistakes

Using <section> without a heading

html
<!-- Wrong: screen reader announces "section" with no label --> <section>Just a paragraph of text.</section> <!-- Right: section implies thematic grouping, needs a heading --> <section> <h2>Why accessibility matters</h2> <p>...</p> </section>

If there is no heading, use <div>.

Using <a> styled as a button

html
<!-- Wrong: keyboard users press Space on a button; links don't respond to Space --> <a href="#" class="btn">Submit</a> <!-- Right: actions use <button>, navigation uses <a> --> <button type="submit">Submit</button>

Screen reader users expect Enter for links and Enter/Space for buttons. Mixing these breaks keyboard navigation.

Nesting multiple <main> elements

html
<!-- Wrong: AT announces multiple "main" landmarks, users get lost --> <main> <main>Content</main> </main>

One <main> per page. Use <section> for subsections inside it.

Adding role="main" to a div instead of <main>

html
<!-- Works today, gone after the next cleanup refactor --> <div role="main" class="content">...</div> <!-- Permanent. No one removes the element itself. --> <main class="content">...</main>

Real-world usage

  • Next.js App Router: <header>, <main>, <nav> go into layout.tsx, wrapping every page
  • Gatsby MDX blogs: each post is wrapped in <article> automatically
  • WordPress block editor: outputs <figure> and <figcaption> for images by default
  • Tailwind UI: semantic base elements with utility classes (<nav class="flex space-x-4">)

Follow-up questions

Q: What is the difference between <section> and <div>?
A: <section> represents a thematic grouping and should have a heading. <div> is purely presentational with no meaning. If you cannot give a section a heading, use <div>.

Q: Can you use <header> inside <article>?
A: Yes. A <header> nested inside <article> acts as the article's own header, not the site header. Only the top-level <header> gets role="banner". Nested ones are just grouping elements.

Q: Does semantic HTML affect SEO?
A: Google parses semantic elements as structural signals. Content inside <article> is indexed differently from content in a generic <div>. <header> and <footer> help the crawler identify page structure, which influences how results are displayed.

Q: A screen reader user hits a <nav> with 50 links. What happens?
A: Some screen readers (like VoiceOver) let users skip landmark regions entirely. Others force tabbing through every link. Fix: add aria-label="Main navigation" to distinguish multiple nav elements, and put a 'Skip to content' link at the very top of the page.

Examples

Blog post structure

html
<article> <header> <h1>Understanding Semantic HTML</h1> <!-- <time> communicates publish date to machines, not only humans --> <time datetime="2026-04-14">April 14, 2026</time> </header> <section> <h2>Why it matters</h2> <p>Screen readers use these elements to build navigation menus for their users.</p> </section> <section> <h2>Common tags</h2> <p>Start with the structural ones: header, main, footer, nav, article, aside.</p> </section> </article>

Screen reader output: 'Article. Heading level 1. Understanding Semantic HTML. April 14, 2026.' With divs instead: 'Div. Div. Div.'

Full page layout with landmarks

html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>ITLead - Interview Prep</title> </head> <body> <header> <a href="/"> <img src="logo.png" alt="ITLead logo"> </a> <nav aria-label="Main navigation"> <ul> <li><a href="/questions">Questions</a></li> <li><a href="/topics">Topics</a></li> </ul> </nav> </header> <main> <article> <h1>What is Semantic HTML?</h1> <p>Content here...</p> </article> <aside aria-label="Related topics"> <h2>You might also like</h2> <ul> <li><a href="/questions/aria">ARIA roles</a></li> </ul> </aside> </main> <footer> <p>&copy; 2026 ITLead</p> </footer> </body> </html>

Every major region is a landmark. A screen reader user can open the landmarks menu and jump directly to 'Main navigation', 'Main', 'Complementary', or 'Content info' without reading a word of content first.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.

Finished reading?