Web accessibility (often abbreviated as "a11y" - "a" followed by 11 letters, then "y") means building websites and applications that everyone can use, regardless of their abilities or disabilities. This includes people with:
Accessibility isn't just about helping a small group of people - it improves the experience for everyone. Captions help people in noisy environments. Keyboard navigation helps power users work faster. Clear language helps non-native speakers understand content.
<aside> 💡
Around 15% of the world's population has some form of disability. That's over 1 billion people. If your website isn't accessible, you're excluding a significant portion of potential users.
</aside>
https://www.youtube.com/watch?v=grrx2Lva7T0
https://www.youtube.com/watch?v=Hp8dAkHQ9O0
Why Accessibility Matters
1. It's the right thing to do The web was invented to be universal. Tim Berners-Lee said: "The power of the Web is in its universality. Access by everyone regardless of disability is an essential aspect."
2. It's often required by law Many countries have laws requiring digital accessibility:
3. It improves SEO Search engines can't see or hear - they rely on the same semantic structure that screen readers use. Good accessibility often means better search rankings.
4. It makes business sense Accessible sites reach more users, have better usability for everyone, and face less legal risk.
5. It makes you a better developer Understanding accessibility deepens your knowledge of HTML, improves code quality, and makes you think about edge cases.
https://www.youtube.com/watch?v=QWPWgaDqbZI
The Web Content Accessibility Guidelines (WCAG) are built on four principles. Content must be:
Users must be able to perceive the information presented. It can't be invisible to all their senses.
Examples:
Users must be able to operate the interface. It can't require interactions they can't perform.
Examples:
Users must be able to understand the information and how to use the interface.
Examples:
Content must be robust enough to work with current and future technologies, including assistive technologies.
Examples:
The foundation of web accessibility is using HTML elements for their intended purpose. Browsers and assistive technologies rely on semantic markup to understand page structure.
Why Semantic Elements Matter
<!-- Bad - no semantic meaning -->
<div class="header">
<div class="nav">
<div class="link">Home</div>
<div class="link">About</div>
</div>
</div>
<div class="main-content">
<div class="article">
<div class="title">Article Title</div>
<div class="content">Article text...</div>
</div>
</div>
<!-- Good - semantic HTML -->
<header>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
</header>
<main>
<article>
<h2>Article Title</h2>
<p>Article text...</p>
</article>
</main>
What screen readers announce:
Bad example: "div, div, div, div with text 'Home', div with text 'About'..." Good example: "banner region, navigation region, link Home, link About, main region, article, heading level 2 Article Title, Article text..."
The semantic version provides context that helps users navigate and understand the page structure.
Landmarks and Page Structure Semantic elements create "landmarks" that screen reader users can jump to:
<body>
<header>
<!-- Screen reader: "banner landmark" -->
<h1>Site Title</h1>
<nav>
<!-- Screen reader: "navigation landmark" -->
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
</header>
<main>
<!-- Screen reader: "main landmark" -->
<h2>Page Title</h2>
<p>Main content...</p>
</main>
<aside>
<!-- Screen reader: "complementary landmark" -->
<h3>Related Links</h3>
<ul>...</ul>
</aside>
<footer>
<!-- Screen reader: "contentinfo landmark" -->
<p>© 2026 Company</p>
</footer>
</body>
Screen reader users can press a key to jump directly to navigation, main content, or other landmarks without listening to the entire page.
Heading Hierarchy
Headings (<h1> through <h6>) create a document outline that helps users understand content structure and navigate efficiently.
<!-- Correct hierarchy -->
<h1>Main Page Title</h1>
<h2>Section 1</h2>
<h3>Subsection 1.1</h3>
<h3>Subsection 1.2</h3>
<h4>Detail 1.2.1</h4>
<h2>Section 2</h2>
<h3>Subsection 2.1</h3>
<!-- Incorrect - skips levels -->
<h1>Main Page Title</h1>
<h4>Don't skip from h1 to h4</h4>
Why this matters:
Best practices:
<h1> per page (the main topic)<aside> ⌨️
Hands On
Open any website and press Cmd+F5 (Mac) or Windows+Ctrl+Enter (Windows) to start VoiceOver or Narrator. Press VO+U (VoiceOver) or H (Narrator) to open the headings list. Notice how you can navigate the page structure just by headings.
</aside>
Every image must have an alt attribute. This text is read aloud by screen readers and displayed when images fail to load.
Good alt text is:
<!-- Good - descriptive and concise -->
<img src="team-meeting.jpg" alt="Five developers collaborating around a laptop">
<!-- Bad - too vague -->
<img src="team-meeting.jpg" alt="team">
<!-- Bad - redundant with "image of" -->
<img src="team-meeting.jpg" alt="Image of developers at a meeting">
<!-- Bad - overly detailed -->
<img src="team-meeting.jpg" alt="Five people, three men and two women, sitting around a silver MacBook Pro laptop in a modern office with white walls and plants">
Is the image decorative only?
YES → alt=""
NO → Continue
Does the image contain text?
YES → Include all text in alt attribute
NO → Continue
Is the image a link or button?
YES → Describe where it goes or what it does
NO → Continue
Is the image complex (chart, diagram)?
YES → Short alt + detailed description elsewhere
NO → Continue
Is the image simple and informative?
YES → Describe what's in the image concisely
Forms are critical interaction points and must be accessible to everyone.
Every form control needs a label. Labels describe what the input is for and create a larger click/tap target.
<!-- Good - label connected to input -->
<label for="email">Email address:</label>
<input type="email" id="email" name="email">
<!-- Also good - wrapping label -->
<label>
Email address:
<input type="email" name="email">
</label>
<!-- Bad - no label -->
<input type="email" name="email" placeholder="Email address">
Why placeholders aren't labels:
<!-- Correct - label + placeholder -->
<label for="email">Email address:</label>
<input
type="email"
id="email"
name="email"
placeholder="[email protected]"
>
Indicate required fields both visually and programmatically:
<!-- Good - visual and programmatic indication -->
<label for="name">
Full name: <span aria-label="required">*</span>
</label>
<input
type="text"
id="name"
name="name"
required
aria-required="true"
>
<!-- At top or bottom of form -->
<p><small>* Required fields</small></p>