Skip to content
intermediatePhase 39 · Accessibility

Semantic HTML for Accessibility

Use semantic elements to convey meaning to assistive technologies.

30m
0 problems
Topic Progress0%

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>
  );
}

Practice Problems

0/3solved
Build Semantic HTML for Accessibility Component

Create a reusable React component implementing Semantic HTML for Accessibility. Include proper state management and accessibility.

Solution
// Production-ready component with:
// - Proper TypeScript types
// - Accessibility (ARIA)
// - Error boundaries
// - Loading states
// - Memoization where needed
Semantic HTML for Accessibility Testing

Write unit and integration tests for Semantic HTML for Accessibility using React Testing Library.

Solution
// Test coverage:
// 1. Rendering tests
// 2. Interaction tests
// 3. Edge case tests
// 4. Accessibility tests
Semantic HTML for Accessibility Performance

Optimize Semantic HTML for Accessibility for performance. Consider memoization, code splitting, and bundle size.

Solution
// Optimization techniques:
// 1. React.memo / useMemo / useCallback
// 2. Code splitting with lazy()
// 3. Virtual scrolling for lists
// 4. Image lazy loading
// 5. Bundle analysis

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 the primary purpose of Semantic HTML for Accessibility?

Question 3 options

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

Question 4 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.

Question

What is Semantic HTML for Accessibility?

Answer

Semantic HTML for Accessibility is a key concept in frontend development.

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>