Skip to content
intermediate Phase 11 · Accessibility

Semantic HTML for Accessibility

Use semantic elements to convey meaning to assistive technologies.

30m
0 problems
Topic Progress 0%

Landmark Regions

Landmark Regions

Use semantic elements to create navigable regions.

Landmark Elements

function App() {
  return (
    <div>
      {/* Banner landmark */}
      <header>
        <nav aria-label="Main navigation">
          <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/about">About</a></li>
          </ul>
        </nav>
      </header>

      {/* Main landmark */}
      <main>
        <article>
          <h1>Page Title</h1>
          <p>Content...</p>
        </article>

        <aside aria-label="Related content">
          <h2>Related</h2>
          <ul>
            <li><a href="/related1">Related 1</a></li>
          </ul>
        </aside>
      </main>

      {/* Contentinfo landmark */}
      <footer>
        <p>&copy; 2024 Company</p>
      </footer>
    </div>
  );
}

Landmark Roles

Element Role Purpose
<header> banner Site-wide header
<nav> navigation Navigation links
<main> main Main content
<aside> complementary Related content
<footer> contentinfo Site-wide footer
<form> form Form content
<section> region Generic region

Multiple Landmarks

function App() {
  return (
    <div>
      <header>{/* Banner */}</header>
      
      <nav aria-label="Main">{/* Primary nav */}</nav>
      <nav aria-label="Footer">{/* Secondary nav */}</nav>
      
      <main>
        <article>{/* Article */}</article>
      </main>
      
      <aside aria-label="Sidebar">{/* Complementary */}</aside>
      
      <footer>{/* Content info */}</footer>
    </div>
  );
}

Skip Links

function SkipLink() {
  return (
    <a href="#main-content" className="skip-link">
      Skip to main content
    </a>
  );
}

function App() {
  return (
    <div>
      <SkipLink />
      <header>{/* ... */}</header>
      <main id="main-content">
        {/* ... */}
      </main>
    </div>
  );
}

Headings Hierarchy

Headings Hierarchy

Create a logical document outline.

Proper Heading Structure

function ArticlePage({ article }) {
  return (
    <article>
      <h1>{article.title}</h1>
      
      <section>
        <h2>Introduction</h2>
        <p>{article.intro}</p>
        
        <h2>Main Content</h2>
        <p>{article.content}</p>
        
        <h3>Subsection</h3>
        <p>{article.subsection}</p>
        
        <h3>Another Subsection</h3>
        <p>{article.another}</p>
      </section>
      
      <section>
        <h2>Conclusion</h2>
        <p>{article.conclusion}</p>
      </section>
    </article>
  );
}

Heading Levels

<h1> Main page title (one per page)
  <h2> Section title
    <h3> Subsection title
      <h4> Sub-subsection title
        <h5> Deep subsection
          <h6> Deepest subsection

Common Mistakes

// ❌ Skipping levels
<h1>Title</h1>
<h3>Subsection</h3> // Skipped h2

// ❌ Multiple h1s
<h1>Header</h1>
<h1>Page Title</h1> // Multiple h1s

// ❌ Using headings for styling
<h1 style={{ fontSize: '12px' }}>Small text</h1> // Wrong use

// ✅ Correct
<h1>Page Title</h1>
<h2>Section</h2>
<h3>Subsection</h3>

ARIA Headings

// When semantic headings aren't possible
<div role="heading" aria-level="2">
  Dynamic Section Title
</div>

// Or use aria-label
<section aria-labelledby="section-title">
  <h2 id="section-title">Section Title</h2>
  <p>Content...</p>
</section>

Lists and Navigation

Lists and Navigation

Use proper list semantics for navigation.

Navigation Lists

function MainNav() {
  return (
    <nav aria-label="Main navigation">
      <ul>
        <li><a href="/">Home</a></li>
        <li><a href="/about">About</a></li>
        <li><a href="/products">Products</a></li>
      </ul>
    </nav>
  );
}

Breadcrumbs

function Breadcrumbs({ items }) {
  return (
    <nav aria-label="Breadcrumb">
      <ol>
        {items.map((item, index) => (
          <li key={item.href}>
            {index < items.length - 1 ? (
              <a href={item.href}>{item.label}</a>
            ) : (
              <span aria-current="page">{item.label}</span>
            )}
          </li>
        ))}
      </ol>
    </nav>
  );
}

// Usage
<Breadcrumbs items={[
  { href: '/', label: 'Home' },
  { href: '/products', label: 'Products' },
  { href: '/products/123', label: 'Product Name' },
]} />

Content Lists

function ProductFeatures({ features }) {
  return (
    <section>
      <h2>Features</h2>
      <ul>
        {features.map(feature => (
          <li key={feature.id}>
            <strong>{feature.title}:</strong> {feature.description}
          </li>
        ))}
      </ul>
    </section>
  );
}

Definition Lists

function ProductSpecs({ specs }) {
  return (
    <dl>
      {specs.map(spec => (
        <div key={spec.name}>
          <dt>{spec.name}</dt>
          <dd>{spec.value}</dd>
        </div>
      ))}
    </dl>
  );
}

Tab Panels

function Tabs({ tabs }) {
  const [activeTab, setActiveTab] = useState(0);

  return (
    <div>
      <div role="tablist" aria-label="Product tabs">
        {tabs.map((tab, index) => (
          <button
            key={tab.id}
            role="tab"
            id={`tab-${tab.id}`}
            aria-selected={index === activeTab}
            aria-controls={`panel-${tab.id}`}
            onClick={() => setActiveTab(index)}
          >
            {tab.label}
          </button>
        ))}
      </div>

      {tabs.map((tab, index) => (
        <div
          key={tab.id}
          role="tabpanel"
          id={`panel-${tab.id}`}
          aria-labelledby={`tab-${tab.id}`}
          hidden={index !== activeTab}
        >
          {tab.content}
        </div>
      ))}
    </div>
  );
}

Quiz

1. What is a landmark region?

Question 1 options

2. How many h1 elements should a page have?

Question 2 options

3. What is a common mistake when implementing Semantic HTML for Accessibility?

Question 3 options

Flashcards

Question

What are landmark regions?

Answer

Semantic HTML elements (header, nav, main, aside, footer) that create navigable regions.

Question

What is proper heading hierarchy?

Answer

Headings should go in order (h1 > h2 > h3) without skipping levels.

Question

Why use semantic HTML?

Answer

It provides meaning to assistive technologies, improving accessibility and SEO.

Question

What is a skip link?

Answer

A link that lets keyboard users skip repetitive navigation to main content.

Revision Notes

Key Takeaways

  • 1. Use landmark elements for screen reader navigation
  • 2. Maintain proper heading hierarchy (h1 > h2 > h3)
  • 3. Use semantic elements for lists and navigation
  • 4. Include skip links for keyboard users
  • 5. Add aria-labels to distinguish multiple landmarks

Interview Tips

  • Explain the purpose of landmark regions
  • Discuss proper heading hierarchy
  • Know how to implement skip links

Cheat Sheet

Semantic HTML Cheat Sheet

Landmark Elements

  • header → banner
  • nav → navigation
  • main → main
  • aside → complementary
  • footer → contentinfo

Headings

  • One h1 per page
  • Don't skip levels
  • Use for structure, not styling

Lists

  • ul/ol for navigation
  • dl for definitions
  • Use role="tablist" for tabs

Skip Links

<a href="#main" className="skip-link">
  Skip to main content
</a>