HTML Semantic Accessibility
1. Semantic HTML5 Elements (nav, main, article, section)
Element
Purpose
Accessibility Impact
Use Case
<header>
Introductory content container
Screen readers identify as banner landmark when top-level
Site/page header with logo, navigation
<nav>
Navigation links container
Creates navigation landmark for quick access
Main menu, breadcrumbs, table of contents
<main>
Primary page content
Defines main landmark, skip to content target
Core article, application interface (one per page)
<article>
Self-contained composition
Independent content region for screen readers
Blog post, news story, widget, forum post
<section>
Thematic content grouping
Creates region with accessible name (use with heading)
Chapters, tabbed panels, themed content blocks
<aside>
Tangentially related content
Complementary landmark for sidebars
Sidebar, pull quotes, related links, ads
<footer>
Footer information
Contentinfo landmark when page-level
Copyright, contact, sitemap links
<figure> / <figcaption>
Self-contained illustration
Associates caption with image for context
Images, diagrams, code snippets with captions
Example: Semantic page structure with landmarks
< header >
< nav aria-label = "Main navigation" >
< ul >
< li >< a href = "/" >Home</ a ></ li >
< li >< a href = "/about" >About</ a ></ li >
</ ul >
</ nav >
</ header >
< main id = "main-content" >
< article >
< h1 >Article Title</ h1 >
< p >Content...</ p >
</ article >
< aside aria-label = "Related articles" >
< h2 >Related Content</ h2 >
</ aside >
</ main >
< footer >
< p > © 2025 Company</ p >
</ footer >
Note: Use one <main> per page and ensure semantic elements
are not nested incorrectly (e.g., no <main> inside <aside>).
2. ARIA Landmark Roles (role="navigation", "main", "banner")
ARIA Role
HTML5 Equivalent
Purpose
Labeling Requirement
role="banner"
<header> (page-level)
Site-wide header with branding
Optional: aria-label if multiple banners
role="navigation"
<nav>
Collection of navigation links
Required : aria-label when multiple navs
role="main"
<main>
Primary content of page
None (only one per page)
role="complementary"
<aside>
Supporting content
Recommended: aria-label for clarity
role="contentinfo"
<footer> (page-level)
Page footer information
None (implied semantics)
role="region"
<section> with name
Generic landmark for important content
Required : aria-labelledby or aria-label
role="search"
None (use role)
Search functionality container
Optional: aria-label "Site search"
role="form"
<form> with name
Form landmark (when named)
Required : aria-label or aria-labelledby
Example: Multiple navigation landmarks with labels
< nav aria-label = "Primary navigation" >
<!-- Main menu -->
</ nav >
< nav aria-label = "Breadcrumb" aria-describedby = "breadcrumb-desc" >
< span id = "breadcrumb-desc" hidden >Current page location</ span >
< ol >
< li >< a href = "/" >Home</ a ></ li >
< li >Current Page</ li >
</ ol >
</ nav >
< div role = "search" >
< form role = "search" aria-label = "Site search" >
< input type = "search" aria-label = "Search query" >
< button type = "submit" >Search</ button >
</ form >
</ div >
Warning: Don't overuse landmarks - too many can be overwhelming. Prefer
HTML5 semantic elements over explicit ARIA roles when available.
3. Heading Hierarchy (h1-h6) Best Practices
Rule
Requirement
Accessibility Impact
Example
Start with H1
One H1 per page describing main topic
Screen reader users navigate by headings; H1 identifies page purpose
<h1>Product Name</h1>
Sequential Order
Don't skip levels (H1→H2→H3, not H1→H3)
Preserves document outline, prevents confusion
H1 > H2 > H3 > H2 > H3
Visual vs Semantic
Use CSS for sizing, not wrong heading level
Maintain logical structure independent of appearance
<h2 class="small"> not <h4>
Section Headings
Every <section> should have a heading
Provides accessible name for region
<section><h2>...</h2></section>
Landmark Headings
Landmarks benefit from descriptive headings
Helps identify region content quickly
<nav><h2>Main Menu</h2></nav>
Hidden Headings
Use visually-hidden class for structure
Provides screen reader navigation without visual clutter
<h2 class="sr-only">Filters</h2>
Example: Proper heading hierarchy
< main >
< h1 >Dashboard</ h1 >
< section >
< h2 >Recent Activity</ h2 >
< article >
< h3 >Task Completed</ h3 >
< p >Details...</ p >
</ article >
</ section >
< section >
< h2 >Statistics</ h2 >
< div >
< h3 >This Month</ h3 >
<!-- Stats -->
</ div >
</ section >
</ main >
❌ Incorrect Hierarchy
< h1 >Page Title</ h1 >
< h4 >Skipped levels</ h4 >
< h2 >Out of order</ h2 >
✅ Correct Hierarchy
< h1 >Page Title</ h1 >
< h2 >Section</ h2 >
< h3 >Subsection</ h3 >
4. Document Language (lang attribute) and Direction
Attribute
Scope
Purpose
Example Value
lang
Document/Element
Specifies language for pronunciation and hyphenation
lang="en", lang="es"
lang (regional)
Element-level
Region-specific language variant
lang="en-US", lang="pt-BR"
dir
Document/Element
Text direction for RTL languages
dir="ltr", dir="rtl"
dir="auto"
Element-level
Automatic direction based on content
dir="auto" for user input
translate
Element
Indicates if content should be translated
translate="no" for brand names
Example: Language and direction declarations
<! DOCTYPE html >
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< title >Multilingual Page</ title >
</ head >
< body >
< h1 >Welcome</ h1 >
<!-- Spanish section -->
< section lang = "es" >
< h2 >Bienvenido</ h2 >
< p >Contenido en español...</ p >
</ section >
<!-- Arabic RTL section -->
< section lang = "ar" dir = "rtl" >
< h2 >مرحبا</ h2 >
< p >محتوى باللغة العربية...</ p >
</ section >
<!-- Brand name not translated -->
< p >Our product < span lang = "en" translate = "no" >AccessibleUI</ span ></ p >
</ body >
</ html >
Common Language Codes
Code
Regional Variants
English
en
en-US, en-GB, en-CA, en-AU
Spanish
es
es-ES, es-MX, es-AR
French
fr
fr-FR, fr-CA, fr-BE
German
de
de-DE, de-AT, de-CH
Arabic (RTL)
ar
ar-SA, ar-EG, ar-AE
Hebrew (RTL)
he
he-IL
Chinese
zh
zh-CN (Simplified), zh-TW (Traditional)
Japanese
ja
ja-JP
Note: Always set lang on <html> element. Screen readers
use this to select proper voice and pronunciation rules.
5. Page Titles and Meta Information
Element/Meta
Purpose
Accessibility Impact
Best Practice
<title>
Browser tab and bookmark text
First thing announced by screen readers; helps identify page
Unique, descriptive, front-load important info
viewport meta
Responsive scaling control
Enables pinch-zoom; critical for low vision users
user-scalable=yes, no maximum-scale
charset meta
Character encoding
Ensures proper text rendering across languages
<meta charset="UTF-8"> always
description meta
Search result snippet
Helps users understand page content before visiting
Concise, accurate, 150-160 characters
theme-color meta
Browser UI color
Visual consistency; supports high contrast needs
Match brand, ensure sufficient contrast
Example: Accessible HTML head structure
<! DOCTYPE html >
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
<!-- Descriptive, unique title (50-60 chars ideal) -->
< title >Product Features - AccessibleUI Design System</ title >
<!-- Clear page description -->
< meta name = "description" content = "Explore accessible UI components
with WCAG 2.2 AA compliance, including buttons, forms, and navigation." >
<!-- Theme color for browser UI -->
< meta name = "theme-color" content = "#007acc" >
<!-- Skip to main content link -->
< link rel = "stylesheet" href = "styles.css" >
</ head >
Title Pattern
Context
Example
Page - Site
General pages
<title>About Us - Company Name</title>
Item - Category - Site
Detail pages
<title>Blue Widget - Products - Store</title>
Status - Action - Site
Form/app states
<title>Error - Checkout - Store</title>
Dynamic Update
SPAs, notifications
<title>(3) Messages - Inbox</title>
Example: Accessible viewport configuration
<!-- ✅ CORRECT: Allows user zoom -->
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
<!-- ❌ WRONG: Disables zoom (WCAG failure) -->
< meta name = "viewport" content = "width=device-width, initial-scale=1.0,
maximum-scale=1.0, user-scalable=no" >
Warning: Never use user-scalable=no or maximum-scale=1.0 - this
violates WCAG 2.2 Success Criterion 1.4.4 (Resize Text) and prevents users from
zooming.
Section 1 Key Takeaways
Use semantic HTML5 elements (header, nav, main, article, aside, footer) for
automatic landmark roles
Ensure proper heading hierarchy (H1→H2→H3) without skipping levels
Always declare lang attribute on <html> element for screen reader
pronunciation
Create unique, descriptive page titles that identify content and context
Never disable zoom/scaling in viewport meta tag
Label multiple landmarks of same type with aria-label for differentiation