Essential HTML Accessibility Fundamentals
1. Semantic HTML5 Elements and Structure
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. Landmark Roles and ARIA Regions
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 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 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