Nextgen Blog
HomeLearnAIQuantumRoboticsSecuritySpaceAbout
Nextgen Blog

By Anubhav — full stack engineer, IIT Mandi CSE. Deep dives into AI, software engineering, and the technologies shaping the next generation of tech.

Navigate

  • Home
  • Learn
  • Blog
  • Archive
  • About

Topics

  • Artificial Intelligence
  • Quantum Computing
  • Robotics
  • Cybersecurity
  • Space Tech

Connect

Built with ❤️ & By - Anubhav

© 2026 Nextgen Blog by Anubhav. All rights reserved.

Privacy PolicyTerms of Service
Phase 03 · Semantic Architecture & SEOChapter 17 of 18
16.
Phase 03Read time ~24 minDifficulty beginner

Accessibility (A11y)

Accessibility, often called A11y, means building websites that can be used by as many people as possible, including people who use:

In this chapter
  • 01What Does A11y Mean?
  • 02Why Accessibility Matters
  • 03Accessibility Is Not Just About Screen Readers
  • 04The Most Important Rule
  • 05Native HTML Gives You Accessibility for Free
  • 06Semantic HTML = Accessibility Foundation
  • 07Headings Are Extremely Important
  • 08Don't Choose Headings Based on Size
  • 09One Main Heading
  • 10Images and alt
  • 11Decorative Images
  • 12Don't Put Useful Information Only in Images
  • 13Forms and Accessibility
  • 14Why Labels Matter
  • 15Label by Wrapping
  • 16Placeholder Is Not a Label
  • 17Why Placeholder-Only Forms Are Bad
  • 18Required Fields
  • 19Fieldsets and Legends
  • 20Checkbox Groups
  • 21Buttons vs Links
  • 22Don't Use Links as Buttons
  • 23Don't Use Buttons for Navigation
  • 24Styling Doesn't Change Semantics
  • 25Keyboard Accessibility
  • 26Focus
  • 27Better Focus Styling
  • 28tabindex
  • 29tabindex="0"
  • 30tabindex="-1"
  • 31Avoid Positive tabindex
  • 32DOM Order Matters
  • 33Skip Links
  • 34Navigation Accessibility
  • 35aria-current
  • 36What Is ARIA?
  • 37The First ARIA Rule
  • 38aria-label
  • 39When aria-label Is Useful
  • 40Don't Overuse aria-label
  • 41aria-labelledby
  • 42aria-describedby
  • 43aria-hidden
  • 44Don't Hide Important Content
  • 45aria-expanded
  • 46aria-controls
  • 47hidden
  • 48ARIA Does Not Create Behavior
  • 49Accessible Modal Dialog
  • 50Accessible Tables
  • 51Accessible Links
  • 52"Read More" Links
  • 53Accessible Icons
  • 54Color Shouldn't Be the Only Signal
  • 55Form Error Messages
  • 56aria-live
  • 57Accessible Search
  • 58input type="search"
  • 59Accessible Navigation Example
  • 60Accessibility Tree
  • 61DOM vs Accessibility Tree
  • 62Accessibility and ARIA Roles
  • 63The "No ARIA" Principle
  • 64Accessibility Checklist
  • 65Structure
  • 66Navigation
  • 67Forms
  • 68Images
  • 69Controls
  • 70Dynamic UI
  • 71Accessibility Testing
  • 72Keyboard
  • 73Screen reader
  • 74Browser accessibility tools
  • 75Automated testing
  • 76Automated Tools Are Not Enough
  • 77WCAG
  • 78Perceivable
  • 79Operable
  • 80Understandable
  • 81Robust
  • 82POUR Example
  • 83Perceivable
  • 84Operable
  • 85Understandable
  • 86Robust
  • 87Complete Accessible Registration Form
  • 88Common Accessibility Mistakes
  • 89❌ Clickable div
  • 90✅ Button
  • 91❌ Image without alt
  • 92✅
  • 93❌ Placeholder-only form
  • 94✅
  • 95❌ Removing focus
  • 96✅
  • 97❌ Generic link text
  • 98✅
  • 99Accessibility Interview Questions
  • 100Q1. What is accessibility?
  • 101Q2. What is A11y?
  • 102Q3. Why is semantic HTML important?
  • 103Q4. What is the difference between alt="" and missing alt?
  • 104Q5. Why shouldn't placeholder replace label?
  • 105Q6. When should you use <button> instead of <a>?
  • 106Q7. What is ARIA?
  • 107Q8. Should you use ARIA everywhere?
  • 108Q9. What is aria-label?
  • 109Q10. What is aria-labelledby?
  • 110Q11. What is aria-describedby?
  • 111Q12. What is aria-expanded?
  • 112Q13. What is a skip link?
  • 113Q14. What is the accessibility tree?
  • 114Mini Project — Fully Accessible Blog Page
  • 115HTML
  • 116Interaction
  • 117Forms
  • 118Test
  • 119Final Accessibility Mental Model
  • 120Next Chapter
  • 121Chapter 16 — Responsive HTML
In this chapter (121 sections)
01What Does A11y Mean?02Why Accessibility Matters03Accessibility Is Not Just About Screen Readers04The Most Important Rule05Native HTML Gives You Accessibility for Free06Semantic HTML = Accessibility Foundation07Headings Are Extremely Important08Don't Choose Headings Based on Size09One Main Heading10Images and alt11Decorative Images12Don't Put Useful Information Only in Images13Forms and Accessibility14Why Labels Matter15Label by Wrapping16Placeholder Is Not a Label17Why Placeholder-Only Forms Are Bad18Required Fields19Fieldsets and Legends20Checkbox Groups21Buttons vs Links22Don't Use Links as Buttons23Don't Use Buttons for Navigation24Styling Doesn't Change Semantics25Keyboard Accessibility26Focus27Better Focus Styling28tabindex29tabindex="0"30tabindex="-1"31Avoid Positive tabindex32DOM Order Matters33Skip Links34Navigation Accessibility35aria-current36What Is ARIA?37The First ARIA Rule38aria-label39When aria-label Is Useful40Don't Overuse aria-label41aria-labelledby42aria-describedby43aria-hidden44Don't Hide Important Content45aria-expanded46aria-controls47hidden48ARIA Does Not Create Behavior49Accessible Modal Dialog50Accessible Tables51Accessible Links52"Read More" Links53Accessible Icons54Color Shouldn't Be the Only Signal55Form Error Messages56aria-live57Accessible Search58input type="search"59Accessible Navigation Example60Accessibility Tree61DOM vs Accessibility Tree62Accessibility and ARIA Roles63The "No ARIA" Principle64Accessibility Checklist65Structure66Navigation67Forms68Images69Controls70Dynamic UI71Accessibility Testing72Keyboard73Screen reader74Browser accessibility tools75Automated testing76Automated Tools Are Not Enough77WCAG78Perceivable79Operable80Understandable81Robust82POUR Example83Perceivable84Operable85Understandable86Robust87Complete Accessible Registration Form88Common Accessibility Mistakes89❌ Clickable div90✅ Button91❌ Image without alt92✅93❌ Placeholder-only form94✅95❌ Removing focus96✅97❌ Generic link text98✅99Accessibility Interview Questions100Q1. What is accessibility?101Q2. What is A11y?102Q3. Why is semantic HTML important?103Q4. What is the difference between alt="" and missing alt?104Q5. Why shouldn't placeholder replace label?105Q6. When should you use <button> instead of <a>?106Q7. What is ARIA?107Q8. Should you use ARIA everywhere?108Q9. What is aria-label?109Q10. What is aria-labelledby?110Q11. What is aria-describedby?111Q12. What is aria-expanded?112Q13. What is a skip link?113Q14. What is the accessibility tree?114Mini Project — Fully Accessible Blog Page115HTML116Interaction117Forms118Test119Final Accessibility Mental Model120Next Chapter121Chapter 16 — Responsive HTML
  • Screen readers
  • Keyboard navigation
  • Screen magnifiers
  • Voice control
  • Switch devices
  • Alternative input devices
  • High-contrast or customized browser settings

Accessibility isn't a separate feature you add at the end.

Good HTML is one of the foundations of accessibility.


1. What Does A11y Mean?#

You may see:

A11y

This is shorthand for:

Accessibility

Why?

A + 11 letters + y

So:

Accessibility
     ↓
A11y

Similarly:

Internationalization → i18n
Localization          → l10n

2. Why Accessibility Matters#

Imagine a website containing:

Logo
Navigation
Search
Products
Checkout

A mouse user may easily click everything.

But imagine someone who navigates entirely with a keyboard:

Tab
 ↓
Tab
 ↓
Tab
 ↓
Enter

Or someone using a screen reader:

"Heading level 1, Online Store"
 
"Navigation"
 
"Link, Home"
 
"Link, Products"
 
"Main"
 
"Button, Add to cart"

For this to work properly, your HTML needs to communicate the meaning and relationships of the content.


3. Accessibility Is Not Just About Screen Readers#

A common misconception is:

Accessibility = screen readers.

That's only one part.

Accessibility includes:

Accessibility
│
├── Vision
│   ├── Screen readers
│   ├── Low vision
│   ├── Magnification
│   └── Color perception
│
├── Hearing
│   └── Captions/transcripts
│
├── Motor
│   ├── Keyboard
│   ├── Switch devices
│   └── Voice control
│
└── Cognitive
    ├── Clear language
    ├── Predictable navigation
    └── Understandable interfaces

4. The Most Important Rule#

Before learning ARIA, remember:

Use native HTML elements whenever possible.

For example:

Correct:

<button type="button">
    Save
</button>

Instead of creating:

<div onclick="save()">
    Save
</div>

Why?

A native button already provides browser accessibility behavior.


5. Native HTML Gives You Accessibility for Free#

Consider:

<button>Submit</button>

The browser already knows:

This is a button

It can generally:

  • Receive keyboard focus
  • Be activated using keyboard interaction
  • Be identified by assistive technologies
  • Participate in forms

Now compare:

<div>Submit</div>

The browser sees:

Generic container

It doesn't automatically know that it's supposed to behave like a button.


6. Semantic HTML = Accessibility Foundation#

You already learned semantic HTML.

Examples:

<header>
<nav>
<main>
<section>
<article>
<aside>
<footer>

These communicate structure.

Instead of:

<div class="header">
    ...
</div>
 
<div class="navigation">
    ...
</div>
 
<div class="content">
    ...
</div>

Prefer:

<header>
    ...
</header>
 
<nav>
    ...
</nav>
 
<main>
    ...
</main>

The second version communicates meaning directly.


7. Headings Are Extremely Important#

A good heading structure:

<h1>HTML Accessibility</h1>
 
<h2>Keyboard Navigation</h2>
 
<h2>Screen Readers</h2>
 
<h2>Accessible Forms</h2>
 
<h3>Labels</h3>
 
<h3>Error Messages</h3>

Think of it as a document outline:

H1 HTML Accessibility
│
├── H2 Keyboard Navigation
│
├── H2 Screen Readers
│
└── H2 Accessible Forms
    │
    ├── H3 Labels
    └── H3 Error Messages

8. Don't Choose Headings Based on Size#

Bad:

<h1>My article</h1>
 
<h4>Important section</h4>

simply because you want the second heading to look smaller.

CSS should control appearance.

<h2>Important section</h2>
h2 {
    font-size: 1.2rem;
}

Meaning comes first.


9. One Main Heading#

A page generally benefits from having a clear primary heading:

<h1>HTML Accessibility Guide</h1>

Then:

<h2>Keyboard Navigation</h2>
<h2>Forms</h2>
<h2>Images</h2>

The exact number of h1 elements isn't the main accessibility issue; what matters most is a clear, logical heading structure.

For a typical document, one primary h1 is a straightforward pattern.


10. Images and alt#

You learned this in Chapter 4.

For meaningful images:

<img
    src="developer.jpg"
    alt="Developer working on a laptop">

The alt text communicates the image's purpose/content when the image can't be perceived.


11. Decorative Images#

Suppose an image is purely decorative:

✨✨✨✨

It doesn't provide meaningful information.

Use:

<img
    src="decoration.svg"
    alt="">

The empty alt tells assistive technology that the image is decorative.

This is different from:

<img src="decoration.svg">

Missing alt and empty alt are not the same thing.


12. Don't Put Useful Information Only in Images#

Bad:

Image contains:
"50% OFF — Sale ends today"

with:

<img src="sale.png" alt="banner">

The important information should exist as actual text when possible.

Better:

<p>
    <strong>50% OFF</strong>
    — Sale ends today.
</p>

If the image adds meaningful context, give it appropriate alternative text.


13. Forms and Accessibility#

Forms are one of the most important accessibility areas.

Bad:

<input type="email" placeholder="Enter email">

There is no persistent programmatic label.

Better:

<label for="email">
    Email address
</label>
 
<input
    id="email"
    name="email"
    type="email">

Now:

Label
  │
  │ for="email"
  ↓
<input id="email">

14. Why Labels Matter#

Suppose a screen reader encounters:

<label for="email">Email address</label>
<input id="email" type="email">

It can understand the relationship:

Email address
    ↓
Input field

Without a label:

<input type="email">

the purpose may be unclear.


15. Label by Wrapping#

Another valid pattern:

<label>
    Email address
 
    <input
        type="email"
        name="email">
</label>

The label and control are associated because the input is inside the label.

Both patterns are valid.

Explicit association is especially useful when you need a label and input separated in the markup:

<label for="email">Email</label>
<input id="email" name="email" type="email">

16. Placeholder Is Not a Label#

This is a very common mistake.

Bad:

<input
    type="email"
    placeholder="Enter your email">

The placeholder is a hint, not a replacement for the label.

Better:

<label for="email">
    Email address
</label>
 
<input
    id="email"
    name="email"
    type="email"
    placeholder="you@example.com">

Now:

Email address
[ you@example.com ]

17. Why Placeholder-Only Forms Are Bad#

Placeholders can:

  • disappear when users type
  • have low contrast
  • be mistaken for already-filled information
  • create accessibility problems
  • make the field's purpose harder to remember

Use:

<label>

for the field's name.

Use:

placeholder=""

only as an optional hint/example.


18. Required Fields#

Use:

<input
    id="email"
    name="email"
    type="email"
    required>

The browser knows:

This field is required.

You can also visually communicate required fields.

For example:

<label for="email">
    Email address
    <span aria-hidden="true">*</span>
</label>

But don't rely solely on the * symbol to communicate the requirement.


19. Fieldsets and Legends#

Suppose you have:

Gender:
○ Male
○ Female
○ Other

A screen reader needs to understand that these radio buttons belong to the same group.

Use:

<fieldset>
    <legend>Gender</legend>
 
    <label>
        <input
            type="radio"
            name="gender"
            value="male">
        Male
    </label>
 
    <label>
        <input
            type="radio"
            name="gender"
            value="female">
        Female
    </label>
 
    <label>
        <input
            type="radio"
            name="gender"
            value="other">
        Other
    </label>
</fieldset>

This gives the group a meaningful name.


20. Checkbox Groups#

Suppose:

Skills:
☐ JavaScript
☐ Python
☐ Java
☐ Go

Use:

<fieldset>
    <legend>Select your skills</legend>
 
    <label>
        <input
            type="checkbox"
            name="skills"
            value="javascript">
        JavaScript
    </label>
 
    <label>
        <input
            type="checkbox"
            name="skills"
            value="python">
        Python
    </label>
 
    <label>
        <input
            type="checkbox"
            name="skills"
            value="java">
        Java
    </label>
</fieldset>

21. Buttons vs Links#

This is one of the most important concepts in accessibility.

Use a link when the user is navigating:

<a href="/profile">
    View profile
</a>

Use a button when the user is performing an action:

<button type="button">
    Delete account
</button>

Think:

Navigate somewhere?
       ↓
      <a>
 
Perform an action?
       ↓
    <button>

22. Don't Use Links as Buttons#

Bad:

<a href="#" onclick="deleteAccount()">
    Delete
</a>

This creates semantic and interaction problems.

Better:

<button type="button" onclick="deleteAccount()">
    Delete
</button>

23. Don't Use Buttons for Navigation#

Bad:

<button onclick="location.href='/about'">
    About
</button>

Better:

<a href="/about">
    About
</a>

Choose the element based on meaning, not appearance.


24. Styling Doesn't Change Semantics#

You can make a link look like a button:

.button-link {
    display: inline-block;
    padding: 10px 16px;
    border-radius: 6px;
}

But:

<a href="/checkout" class="button-link">
    Checkout
</a>

is still a link.

Its visual appearance doesn't change its semantic role.


25. Keyboard Accessibility#

A website should be usable without a mouse.

Common keyboard keys:

Tab
Shift + Tab
Enter
Space
Arrow keys
Escape

For example:

Tab
 ↓
Logo link
 ↓
Home
 ↓
Products
 ↓
Search
 ↓
Add to cart

Users should be able to understand where keyboard focus is.


26. Focus#

When an element receives keyboard focus, browsers commonly provide a visual focus indicator.

For example:

Normal:
 
[ Submit ]
 
Focused:
 
[ Submit ]  ← visible focus indicator

Don't remove it without providing an equivalent accessible focus style.

Bad CSS:

button:focus {
    outline: none;
}

This can make keyboard navigation extremely difficult.


27. Better Focus Styling#

For example:

button:focus-visible,
a:focus-visible {
    outline: 3px solid currentColor;
    outline-offset: 3px;
}

focus-visible is particularly useful because it allows you to style focus when it is relevant to the user's interaction mode.


28. tabindex#

You may encounter:

tabindex="0"

and:

tabindex="-1"

tabindex="0"#

Adds an element to the normal sequential keyboard navigation order.

<div tabindex="0">
    Custom control
</div>

But this doesn't automatically make a div behave like a button.

tabindex="-1"#

The element isn't normally reached by sequential Tab navigation, but can receive programmatic focus.

element.focus();

29. Avoid Positive tabindex#

Avoid:

tabindex="1"
tabindex="2"
tabindex="3"

Positive tabindex values can create a confusing custom focus order.

Prefer natural DOM order:

<header>
    ...
</header>
 
<main>
    ...
</main>

and let the browser manage normal keyboard traversal.


30. DOM Order Matters#

Consider:

<div class="left">
    Navigation
</div>
 
<div class="right">
    Main content
</div>

CSS may visually put the main content first.

But keyboard and assistive technology navigation generally follows the document structure.

So:

Make the HTML order meaningful before using CSS to change visual layout.


31. Skip Links#

Imagine a page with:

Logo
Navigation
50 navigation links
Social links
Ads
Main content

A keyboard user shouldn't have to press Tab dozens of times before reaching the content.

A skip link can help:

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

Then:

<main id="main-content">
    ...
</main>

Conceptually:

Tab
 ↓
Skip to main content
 ↓
Enter
 ↓
Main content

This is extremely useful on complex websites.


32. Navigation Accessibility#

Use:

<nav aria-label="Main navigation">
    <ul>
        <li>
            <a href="/">Home</a>
        </li>
 
        <li>
            <a href="/blog">Blog</a>
        </li>
 
        <li>
            <a href="/contact">Contact</a>
        </li>
    </ul>
</nav>

If there are multiple navigation regions:

<nav aria-label="Main navigation">
    ...
</nav>
 
<nav aria-label="Footer navigation">
    ...
</nav>

This gives assistive technology useful context.


33. aria-current#

Suppose the current page is Blog:

<nav aria-label="Main navigation">
    <a href="/">Home</a>
 
    <a
        href="/blog"
        aria-current="page">
        Blog
    </a>
 
    <a href="/contact">
        Contact
    </a>
</nav>

aria-current="page" communicates:

This link represents the current page.

Other values exist for other contexts, such as:

page
step
location
date
time
true
false

34. What Is ARIA?#

ARIA stands for:

Accessible Rich Internet Applications

It provides additional accessibility semantics through attributes such as:

aria-label
aria-labelledby
aria-describedby
aria-hidden
aria-expanded
aria-controls
aria-current
aria-live

But remember:

ARIA should complement HTML, not replace semantic HTML.


35. The First ARIA Rule#

A very useful principle:

If a native HTML element already provides the required semantics, prefer the native element.

For example:

Don't do:

<div role="button">
    Save
</div>

when you can do:

<button>
    Save
</button>

Native HTML is usually simpler and more robust.


36. aria-label#

You can give an accessible name using:

<button aria-label="Close">
    ×
</button>

The visible symbol is:

×

But assistive technology can identify the control as:

Close

37. When aria-label Is Useful#

Consider an icon-only button:

<button>
    🔍
</button>

The meaning may not be sufficiently clear.

Better:

<button aria-label="Search">
    🔍
</button>

Another:

<button aria-label="Close dialog">
    ×
</button>

38. Don't Overuse aria-label#

Don't write:

<h1 aria-label="HTML Tutorial">
    HTML Tutorial
</h1>

when the visible text already provides the accessible name.

Prefer:

<h1>
    HTML Tutorial
</h1>

ARIA should solve an actual semantic/accessibility need.


39. aria-labelledby#

Suppose a dialog has:

<h2 id="dialog-title">
    Delete account
</h2>

You can associate the dialog with that visible heading:

<div
    role="dialog"
    aria-labelledby="dialog-title">
 
    <h2 id="dialog-title">
        Delete account
    </h2>
 
</div>

Now the accessible name comes from the visible heading.

This is often preferable to duplicating the text in aria-label.


40. aria-describedby#

Suppose:

<label for="password">
    Password
</label>
 
<input
    id="password"
    type="password"
    aria-describedby="password-help">
 
<p id="password-help">
    Password must contain at least 8 characters.
</p>

The relationship is:

Password
   │
   ↓
Input
   │
   ↓
Additional description
   │
   ↓
password-help

Assistive technology can use the description to provide additional context.


41. aria-hidden#

Example:

<span aria-hidden="true">
    ✨
</span>

This can hide an element from the accessibility tree.

Useful for decorative content that doesn't need to be announced.

For example:

<button>
    <span aria-hidden="true">🔍</span>
    Search
</button>

The visible icon is decorative because the text already says:

Search

42. Don't Hide Important Content#

Bad:

<p aria-hidden="true">
    Your payment failed.
</p>

If the user needs this information, don't hide it from assistive technologies.

aria-hidden="true" should be used intentionally.


43. aria-expanded#

Useful for expandable controls.

Example:

<button
    aria-expanded="false"
    aria-controls="menu">
    Menu
</button>
 
<nav id="menu" hidden>
    ...
</nav>

When open:

<button
    aria-expanded="true"
    aria-controls="menu">
    Menu
</button>

The attribute communicates state:

false → collapsed
true  → expanded

44. aria-controls#

This identifies the element controlled by a control.

<button
    aria-expanded="false"
    aria-controls="mobile-menu">
    Menu
</button>
 
<nav id="mobile-menu">
    ...
</nav>

Relationship:

Button
  │
  │ aria-controls
  ↓
mobile-menu

JavaScript would normally update the state and visibility.


45. hidden#

HTML provides a native mechanism:

<div hidden>
    Hidden content
</div>

The browser treats the element as hidden.

For a menu:

<nav id="mobile-menu" hidden>
    ...
</nav>

Then JavaScript can remove hidden when opening it.

This is often preferable to using ARIA alone to indicate visibility.


46. ARIA Does Not Create Behavior#

This is a critical concept.

If you write:

<button
    aria-expanded="false"
    aria-controls="menu">
    Menu
</button>

ARIA communicates state.

It does not automatically create the menu behavior.

You still need appropriate HTML/CSS/JavaScript to:

Click Menu
    ↓
Open menu
    ↓
Update aria-expanded
    ↓
Show menu

ARIA describes accessibility state; it doesn't implement the interaction.


47. Accessible Modal Dialog#

A simplified example:

<div
    role="dialog"
    aria-modal="true"
    aria-labelledby="dialog-title">
 
    <h2 id="dialog-title">
        Delete account
    </h2>
 
    <p>
        Are you sure you want to delete your account?
    </p>
 
    <button type="button">
        Cancel
    </button>
 
    <button type="button">
        Delete account
    </button>
 
</div>

But a truly accessible modal also requires proper JavaScript focus management.

For example:

Open dialog
    ↓
Move focus into dialog
    ↓
User interacts
    ↓
Escape can close when appropriate
    ↓
Restore focus to triggering element

ARIA alone isn't enough.


48. Accessible Tables#

You learned tables earlier.

Use:

<table>
    <caption>Employee salaries</caption>
 
    <thead>
        <tr>
            <th scope="col">Employee</th>
            <th scope="col">Department</th>
            <th scope="col">Salary</th>
        </tr>
    </thead>
 
    <tbody>
        <tr>
            <th scope="row">Anubhav</th>
            <td>Engineering</td>
            <td>₹26.5 LPA</td>
        </tr>
    </tbody>
</table>

Important accessibility features:

caption
th
scope
logical structure

49. Accessible Links#

Bad:

<a href="/article">Click here</a>

Better:

<a href="/article">
    Read the HTML accessibility guide
</a>

Why?

A screen reader user may navigate through links separately.

Imagine hearing:

Link, click here
Link, click here
Link, click here

That's not useful.

Instead:

Link, Read the HTML accessibility guide
Link, Download the PDF guide
Link, View the pricing page

The destination is clear.


50. "Read More" Links#

If multiple cards contain:

<a href="/article-1">Read more</a>
<a href="/article-2">Read more</a>
<a href="/article-3">Read more</a>

The visible text is ambiguous when links are encountered out of context.

Better:

<a href="/article-1">
    Read more about AI agents
</a>
 
<a href="/article-2">
    Read more about RAG
</a>
 
<a href="/article-3">
    Read more about vector databases
</a>

Or provide the article title as the link itself.


51. Accessible Icons#

Suppose:

<button>
    ❤️
</button>

What does it mean?

Maybe:

Like
Favorite
Remove
Delete

Make the purpose clear:

<button aria-label="Add to favorites">
    ❤️
</button>

Or:

<button>
    <span aria-hidden="true">❤️</span>
    Add to favorites
</button>

52. Color Shouldn't Be the Only Signal#

Bad:

Red = Error
Green = Success

Some users may not distinguish colors reliably.

Better:

❌ Error: Password is too short.

and:

✓ Account created successfully.

The color can still reinforce the meaning, but shouldn't be the only way the information is communicated.


53. Form Error Messages#

Bad:

Email field turns red.

That's not enough.

Better:

<label for="email">
    Email address
</label>
 
<input
    id="email"
    name="email"
    type="email"
    aria-describedby="email-error">
 
<p id="email-error">
    Enter a valid email address.
</p>

Now the error is actual text.

For dynamic validation, you may also need appropriate focus management and live-region techniques depending on the interaction.


54. aria-live#

aria-live can communicate dynamically updated content to assistive technologies.

Example:

<div aria-live="polite">
</div>

JavaScript might later insert:

"Your profile has been saved."

The browser/assistive technology can announce the update depending on the live-region configuration and assistive technology behavior.

Common values:

off
polite
assertive

Use assertive carefully because interrupting a user's current speech can be disruptive.


55. Accessible Search#

A search form can be:

<form role="search" action="/search" method="get">
 
    <label for="search">
        Search
    </label>
 
    <input
        id="search"
        name="q"
        type="search">
 
    <button type="submit">
        Search
    </button>
 
</form>

Because the form has:

role="search"

assistive technology can identify it as a search landmark.


56. input type="search"#

HTML provides:

<input type="search">

Use it when the field represents a search query.

<label for="site-search">
    Search
</label>
 
<input
    id="site-search"
    name="q"
    type="search">

This is more meaningful than simply:

<input type="text">

when the field's purpose is searching.


57. Accessible Navigation Example#

<a href="#main-content" class="skip-link">
    Skip to main content
</a>
 
<header>
    <a href="/" aria-label="NextGen Blog home">
        NextGen Blog
    </a>
 
    <nav aria-label="Main navigation">
        <ul>
            <li>
                <a href="/" aria-current="page">
                    Home
                </a>
            </li>
 
            <li>
                <a href="/ai">
                    AI
                </a>
            </li>
 
            <li>
                <a href="/web-development">
                    Web Development
                </a>
            </li>
 
            <li>
                <a href="/contact">
                    Contact
                </a>
            </li>
        </ul>
    </nav>
</header>
 
<main id="main-content">
    ...
</main>

Notice how many accessibility features come simply from using good HTML.


58. Accessibility Tree#

The browser doesn't only create a DOM.

Conceptually:

HTML
 ↓
DOM
 ↓
Accessibility Tree
 ↓
Assistive Technology

For example:

<button>
    Save
</button>

The browser can expose something conceptually like:

Role: button
Name: Save
State: enabled

A screen reader can then announce something like:

"Save, button"

The exact announcement depends on the browser and assistive technology.


59. DOM vs Accessibility Tree#

Think:

                 HTML
                  │
          ┌───────┴───────┐
          ↓               ↓
         DOM      Accessibility Tree
          │               │
          ↓               ↓
    Web application   Assistive tech

Semantic HTML helps the browser build a meaningful accessibility representation.


60. Accessibility and ARIA Roles#

You may encounter:

<div role="button">

or:

<div role="dialog">

or:

<div role="alert">

ARIA roles communicate semantics.

Examples:

button
dialog
alert
navigation
search
tab
tabpanel
status

But again:

Don't use ARIA to recreate native HTML unnecessarily.

Prefer:

<button>

over:

<div role="button">

61. The "No ARIA" Principle#

A useful progression is:

1. Native HTML
       ↓
2. HTML + CSS
       ↓
3. HTML + CSS + JavaScript
       ↓
4. ARIA only when necessary

Not:

<div>
<div>
<div role="button">
<div aria-label="...">
<div tabindex="0">

when native elements could solve the problem.


62. Accessibility Checklist#

Before shipping a page, check:

Structure#

✓ Correct language
✓ Logical headings
✓ Semantic elements
✓ Meaningful landmarks

Navigation#

✓ Keyboard accessible
✓ Visible focus
✓ Logical tab order
✓ Skip link where useful

Forms#

✓ Labels
✓ Instructions
✓ Errors
✓ Required state
✓ Group related controls

Images#

✓ Meaningful alt
✓ Decorative alt=""
✓ No important information only in images

Controls#

✓ Native buttons
✓ Native links
✓ Keyboard operation
✓ Accessible names

Dynamic UI#

✓ State communicated
✓ Focus managed
✓ Dynamic updates announced when necessary

63. Accessibility Testing#

Don't just inspect the source code.

Test with:

1. Keyboard#

Unplug your mouse or simply don't use it.

Try:

Tab
Shift + Tab
Enter
Space
Arrow keys
Escape

Can you complete the task?


2. Screen reader#

Common screen readers include:

NVDA
JAWS
VoiceOver
TalkBack

You can test how your page is announced.


3. Browser accessibility tools#

Modern browser developer tools provide accessibility inspection features.

You can inspect:

Role
Name
State
Properties

4. Automated testing#

Tools such as:

axe
Lighthouse
Accessibility Insights

can identify many common problems.

But automated tools don't detect everything.


64. Automated Tools Are Not Enough#

Suppose an automated scanner says:

100% accessibility

That does not prove the website is fully accessible.

Why?

A tool may detect:

Missing alt
Missing label
Color contrast
Invalid ARIA

But it may not understand whether:

The keyboard flow makes sense.
The error message is understandable.
The interaction is confusing.
The focus moves correctly.
The content itself is clear.

Human testing still matters.


65. WCAG#

You will often hear:

WCAG

It stands for:

Web Content Accessibility Guidelines

WCAG provides internationally recognized accessibility guidance.

The four high-level principles are:

P
O
U
R

Perceivable#

Users must be able to perceive the information.

Operable#

Users must be able to operate the interface.

Understandable#

Users must be able to understand the content and interaction.

Robust#

Content should work with different user agents and assistive technologies.


66. POUR Example#

Imagine a video:

Perceivable#

Provide captions:

<track kind="captions">

Operable#

Allow keyboard controls.

Understandable#

Use clear controls.

Robust#

Use proper HTML and standards so assistive technologies can interpret it.


67. Complete Accessible Registration Form#

Here's a practical example combining several concepts:

<form action="/register" method="post">
 
    <h1>Create an Account</h1>
 
    <div>
        <label for="name">
            Full name
        </label>
 
        <input
            id="name"
            name="name"
            type="text"
            autocomplete="name"
            required>
    </div>
 
    <div>
        <label for="email">
            Email address
        </label>
 
        <input
            id="email"
            name="email"
            type="email"
            autocomplete="email"
            required
            aria-describedby="email-help">
 
        <p id="email-help">
            We'll use this address for account notifications.
        </p>
    </div>
 
    <div>
        <label for="password">
            Password
        </label>
 
        <input
            id="password"
            name="password"
            type="password"
            autocomplete="new-password"
            minlength="8"
            required
            aria-describedby="password-help">
 
        <p id="password-help">
            Password must contain at least 8 characters.
        </p>
    </div>
 
    <fieldset>
 
        <legend>Preferred contact method</legend>
 
        <label>
            <input
                type="radio"
                name="contact"
                value="email"
                checked>
            Email
        </label>
 
        <label>
            <input
                type="radio"
                name="contact"
                value="phone">
            Phone
        </label>
 
    </fieldset>
 
    <label>
        <input
            type="checkbox"
            name="terms"
            required>
        I agree to the terms and conditions.
    </label>
 
    <button type="submit">
        Create account
    </button>
 
</form>

Notice how much accessibility we get from native HTML:

label
fieldset
legend
button
input
required
autocomplete
aria-describedby

68. Common Accessibility Mistakes#

❌ Clickable div#

<div onclick="openMenu()">
    Menu
</div>

✅ Button#

<button type="button">
    Menu
</button>

❌ Image without alt#

<img src="profile.jpg">

✅

<img
    src="profile.jpg"
    alt="Anubhav smiling">

❌ Placeholder-only form#

<input placeholder="Email">

✅#

<label for="email">
    Email
</label>
 
<input
    id="email"
    placeholder="you@example.com">

❌ Removing focus#

*:focus {
    outline: none;
}

✅#

Provide a clear focus indicator.


❌ Generic link text#

<a href="/guide">
    Click here
</a>

✅#

<a href="/guide">
    Read the HTML accessibility guide
</a>

69. Accessibility Interview Questions#

Q1. What is accessibility?#

The practice of making websites usable by people with different abilities and assistive technologies.


Q2. What is A11y?#

A shorthand for accessibility.


Q3. Why is semantic HTML important?#

Because it communicates the meaning and structure of content to browsers, assistive technologies, developers, and other tools.


Q4. What is the difference between alt="" and missing alt?#

alt=""

explicitly identifies the image as having no alternative text, commonly appropriate for decorative images.

A missing alt does not communicate that intentional decision and can lead to poor or inconsistent accessibility behavior.


Q5. Why shouldn't placeholder replace label?#

Because placeholders are temporary hints and are not a reliable replacement for a persistent field label.


Q6. When should you use <button> instead of <a>?#

Use <button> for actions and <a> for navigation.


Q7. What is ARIA?#

Accessible Rich Internet Applications — a set of attributes that provide additional accessibility semantics and states.


Q8. Should you use ARIA everywhere?#

No.

Prefer native semantic HTML whenever it provides the required behavior and semantics.


Q9. What is aria-label?#

It provides an accessible name for an element when appropriate.

Example:

<button aria-label="Close">
    ×
</button>

Q10. What is aria-labelledby?#

It associates an element with another element that provides its accessible name.


Q11. What is aria-describedby?#

It associates an element with additional descriptive content.


Q12. What is aria-expanded?#

It communicates whether an expandable control is currently expanded or collapsed.


Q13. What is a skip link?#

A link that allows keyboard users to bypass repetitive navigation and move directly to the main content.


Q14. What is the accessibility tree?#

A browser-generated representation of relevant UI semantics that assistive technologies can consume.


70. Mini Project — Fully Accessible Blog Page#

Build:

accessible-blog.html

Structure:

Skip to main content
        ↓
Header
        ↓
Accessible navigation
        ↓
Main
 ├── Article
 │    ├── H1
 │    ├── Author
 │    ├── Image
 │    ├── Content
 │    ├── H2
 │    ├── H2
 │    └── Related links
 │
 └── Aside
      └── Related articles
        ↓
Footer

Requirements:

HTML#

✓ Semantic HTML
✓ Correct headings
✓ lang attribute
✓ Accessible navigation
✓ Meaningful image alt
✓ Accessible links
✓ Skip link
✓ Main landmark
✓ Aside
✓ Footer

Interaction#

✓ Keyboard navigation
✓ Visible focus
✓ No clickable divs
✓ Buttons used for actions
✓ Links used for navigation

Forms#

Add:

✓ Search form
✓ Label
✓ Search input
✓ Submit button

Test#

Try to use the entire website:

WITHOUT A MOUSE

That is one of the best beginner accessibility exercises.


71. Final Accessibility Mental Model#

When writing HTML, ask:

                    HTML Element
                         │
                         ↓
                  What does it mean?
                         │
          ┌──────────────┼──────────────┐
          ↓              ↓              ↓
       Browser      Screen Reader    Keyboard
          │              │              │
          └──────────────┼──────────────┘
                         ↓
                   User Experience

The most important rule is:

Choose HTML based on meaning, not appearance.

Use:

<button>

when it's a button.

Use:

<a>

when it's a link.

Use:

<nav>

for navigation.

Use:

<main>

for the main content.

Use:

<label>

for form controls.

Use:

<h1>–<h6>

for document headings.

Use ARIA when native HTML doesn't adequately express the required semantics.

That single principle will prevent a huge number of accessibility problems.


Next Chapter#

Chapter 16 — Responsive HTML#

Next we'll learn how HTML works with responsive design, including:

  • Mobile-first thinking
  • Responsive images
  • srcset
  • sizes
  • <picture>
  • Responsive video
  • Viewport
  • Mobile HTML architecture
  • Responsive navigation
  • Tables on mobile
  • Responsive forms
  • Touch-friendly controls
  • Mobile accessibility
  • Desktop vs mobile page structure
  • Responsive embeds
  • HTML + CSS responsive patterns
  • Real-world responsive website structure
  • Common responsive mistakes
  • Interview questions
  • A complete responsive webpage project

Finished this chapter?

Mark it as complete to track your mastery.

Previous ChapterChapter 14 — Metadata & `<head>`Next ChapterChapter 16 — Responsive HTML
PrevNext