Semantic HTML & Accessibility
Most frontend engineers can build any UI with div and span. Senior engineers know why that's the wrong approach â and can articulate the real cost.
Why Semantics Matter
Semantic HTML provides three things for free:
- Accessibility â screen readers use the DOM tree, not visual appearance, to convey structure
- SEO â search engines weigh semantic elements for content understanding
- Maintainability â
<nav>communicates intent to developers;<div class="nav">does not
Landmark Roles
HTML5 landmarks create a navigable structure for assistive technology. Screen reader users can jump between landmarks the way sighted users scan a page visually.
| Element | Implicit Role | Purpose |
|---|---|---|
<header> | banner (when top-level) | Site header, branding |
<nav> | navigation | Primary and secondary navigation |
<main> | main | Primary page content (one per page) |
<aside> | complementary | Sidebar, related content |
<footer> | contentinfo (when top-level) | Site footer, legal info |
<section> | region (with accessible name) | Thematic grouping of content |
<article> | article | Self-contained, redistributable content |
<body>
<header>
<nav aria-label="Primary">...</nav>
</header>
<main>
<article>
<h1>Page Title</h1>
<section aria-labelledby="intro-heading">
<h2 id="intro-heading">Introduction</h2>
</section>
</article>
</main>
<aside aria-label="Related articles">...</aside>
<footer>...</footer>
</body>ARIA: The Escape Hatch, Not the Default
ARIA (Accessible Rich Internet Applications) attributes add semantics when native HTML falls short. The first rule of ARIA: don't use ARIA if a native element will do the job.
<!-- Bad: ARIA reimplements a native element -->
<div role="button" tabindex="0" onclick="handleClick()">Submit</div>
<!-- Good: native element gets behavior for free -->
<button onclick="handleClick()">Submit</button>Native <button> gives you: keyboard activation (Enter/Space), focus management, form submission, and announced role â all without a single ARIA attribute.
Essential ARIA Patterns
<!-- Live regions: announce dynamic content to screen readers -->
<div aria-live="polite" aria-atomic="true">
3 items in your cart
</div>
<!-- Expanded/collapsed state -->
<button aria-expanded="false" aria-controls="menu-content">
Menu
</button>
<div id="menu-content" hidden>...</div>
<!-- Labeling without visible text -->
<button aria-label="Close dialog">
<svg>...</svg>
</button>Forms Accessibility
Forms are where accessibility most directly impacts user experience:
<form>
<div>
<label for="email">Email address</label>
<input
id="email"
type="email"
required
aria-describedby="email-hint email-error"
/>
<p id="email-hint">We'll never share your email.</p>
<p id="email-error" role="alert" hidden>
Please enter a valid email address.
</p>
</div>
</form>Key patterns:
- Every input needs a label â
<label for>oraria-labelfor icon-only inputs - Error messages use
aria-describedbyâ links the error to the input for screen readers role="alert"oraria-liveâ announces dynamic validation errors- Group related inputs with
<fieldset>and<legend>(radio groups, address fields)
Heading Hierarchy
Screen reader users navigate by headings more than any other method. The hierarchy must be logical:
<!-- Correct: logical hierarchy -->
<h1>Dashboard</h1>
<h2>Recent Activity</h2>
<h2>Analytics</h2>
<h3>Traffic Sources</h3>
<h3>Conversion Rate</h3>
<!-- Broken: skipped levels, multiple h1s -->
<h1>Dashboard</h1>
<h1>Analytics</h1>
<h4>Traffic</h4>Never choose heading level for visual size â use CSS for that. Heading level communicates document structure.
Screen Reader Testing Mental Model
You don't need a screen reader to write accessible HTML, but you need to think in terms of the accessibility tree â the parallel DOM that assistive technology reads.
Every interactive element needs:
- Name â what is it? (label, text content,
aria-label) - Role â what does it do? (button, link, checkbox)
- State â what's its current condition? (expanded, selected, disabled)
Interview Signal
Accessibility questions in senior interviews test whether you treat a11y as an afterthought or a design constraint. Strong signals:
- Default to native elements â knowing what
<button>,<dialog>,<details>give you for free - ARIA as a last resort â not as a replacement for semantic HTML
- Testing awareness â mentioning axe, Lighthouse, or screen reader testing as part of your workflow
- Legal/business framing â understanding that accessibility is both a legal requirement (WCAG, ADA) and a business advantage