HTML Accessibility & ARIA
HTML Accessibility & ARIA
Web accessibility means designing and developing websites so that people with different abilities can use, understand, navigate and interact with them.
Accessibility benefits users who may have visual, auditory, physical, speech, cognitive or neurological disabilities. It also improves usability for many users in general.
HTML accessibility begins with using the correct semantic HTML element for the job. ARIA should supplement good HTML, not replace it.
1. Why Web Accessibility Matters
A website that looks attractive but cannot be operated by some users is not a truly inclusive website.
Accessibility helps users:
- Navigate websites using keyboards.
- Understand content through screen readers.
- Complete forms correctly.
- Understand images through alternative text.
- Identify buttons, links and interactive controls.
- Operate websites without relying exclusively on a mouse.
Accessibility should be considered during planning and development rather than added as a final correction.
2. Assistive Technologies
Assistive technologies help people interact with digital content in ways that meet their individual needs.
| Technology | Purpose |
|---|---|
| Screen Reader | Reads and communicates webpage content to the user. |
| Screen Magnifier | Enlarges content on the screen. |
| Keyboard Navigation | Allows interaction without a mouse. |
| Voice Control | Allows users to operate devices using speech. |
| Switch Devices | Provides alternative methods for interacting with controls. |
3. Semantic HTML and Accessibility
Semantic HTML elements communicate the meaning and purpose of content to browsers and assistive technologies.
Good Example
<button type="button">
Save Changes
</button>
Poor Replacement
<div>
Save Changes
</div>
A native <button> already provides important semantics and interaction behavior.
Prefer native HTML elements whenever they provide the required functionality.
4. Semantic Elements That Support Accessibility
| Element | Purpose |
|---|---|
| <header> | Introductory or navigational content. |
| <nav> | Major navigation links. |
| <main> | Primary content of the document. |
| <article> | Self-contained content. |
| <section> | Thematic grouping of content. |
| <aside> | Complementary content. |
| <footer> | Footer information or navigation. |
| <button> | Interactive button control. |
| <form> | Groups controls used to collect and submit data. |
5. Accessible Heading Structure
Headings provide a logical hierarchy that helps users understand and navigate a document.
<h1>Web Accessibility</h1>
<h2>Accessibility Fundamentals</h2>
<h3>Semantic HTML</h3>
<h3>Keyboard Accessibility</h3>
<h2>ARIA</h2>
<h3>ARIA Roles</h3>
<h3>ARIA States and Properties</h3>
Do not choose heading levels merely because a particular heading size looks attractive. Use headings according to the content hierarchy.
6. Accessible Links
Link text should clearly describe the destination or action.
Good Example
<a href="/html/forms">
Learn HTML Forms
</a>
Poor Example
<a href="/html/forms">
Click here
</a>
Meaningful link text provides useful context, especially when users navigate through links independently.
7. Accessible Images and Alt Text
Informative images should have meaningful alternative text using the alt attribute.
<img
src="accessibility-chart.png"
alt="Chart showing the four principles of web accessibility">
Decorative Image
If an image is purely decorative and provides no meaningful information, an empty alt attribute can be appropriate.
<img
src="decorative-line.png"
alt="">
Do not write unnecessary descriptions for decorative images, and do not stuff keywords into alt text.
8. Accessible Forms
Form controls should have clear, programmatically associated labels.
Recommended Example
<label for="email">
Email Address
</label>
<input
type="email"
id="email"
name="email">
The for attribute of the label matches the id of the input.
| Attribute / Element | Purpose |
|---|---|
| <label> | Provides a visible label for a form control. |
| for | Associates the label with a control's id. |
| id | Provides the identifier referenced by the label. |
| required | Indicates that input is required. |
| aria-describedby | Associates additional descriptive information. |
9. Group Related Form Controls
Use <fieldset> and <legend> when several controls form a logical group.
<fieldset>
<legend>Preferred Contact Method</legend>
<label>
<input
type="radio"
name="contact"
value="email">
Email
</label>
<label>
<input
type="radio"
name="contact"
value="phone">
Phone
</label>
</fieldset>
The legend provides a meaningful description for the group.
10. Use Buttons for Actions
Use <button> for actions performed on the current page or application.
<button type="button">
Open Menu
</button>
Use <a> for navigation to another URL.
<a href="/courses">
View Courses
</a>
| Requirement | Preferred Element |
|---|---|
| Navigate to another page | <a> |
| Perform an action | <button> |
11. Keyboard Accessibility
Users should be able to operate essential functionality without requiring a mouse.
Common keyboard interactions include:
- Tab — move between interactive elements.
- Shift + Tab — move backward.
- Enter — activate links and some controls.
- Space — commonly activates buttons and toggles.
- Arrow keys — may operate specific widgets.
- Escape — commonly closes dialogs or menus.
Try navigating the complete webpage using only the keyboard. If an important control cannot be reached or operated, investigate the accessibility problem.
12. Keyboard Focus
Keyboard users need a visible indication of which element currently has focus.
Native interactive elements generally provide useful keyboard behavior and focus handling.
<button type="button">
Submit
</button>
Do not remove visible focus indicators simply because they do not match the visual design.
13. Understanding tabindex
The tabindex attribute controls aspects of keyboard focus behavior.
Natural Keyboard Order
<button type="button">
Save
</button>
Native controls normally participate in keyboard navigation without requiring tabindex.
tabindex="0"
<div tabindex="0">
Custom interactive element
</div>
A value of 0 places the element in the normal sequential keyboard navigation order.
Do not use positive tabindex values to create an artificial keyboard order. They can make keyboard navigation difficult to maintain.
14. What is ARIA?
ARIA stands for Accessible Rich Internet Applications.
ARIA is a set of attributes that can communicate roles, states and properties of user-interface elements to assistive technologies.
ARIA is especially useful for custom widgets and dynamic interfaces where native HTML semantics alone are not sufficient.
No ARIA is better than bad ARIA.
First look for a native HTML element that already provides the required semantics and behavior.
15. ARIA Roles
An ARIA role communicates what type of interface element an object represents.
<div role="button">
Save
</div>
However, if the element is actually a button, the native element should normally be preferred:
<button type="button">
Save
</button>
| ARIA Role | Conceptual Purpose |
|---|---|
| button | Represents a button-like control. |
| dialog | Represents a dialog window. |
| navigation | Represents navigation content. |
| tab | Represents a tab in a tab interface. |
| tabpanel | Represents content associated with a tab. |
| alert | Represents important dynamic information. |
16. aria-label
aria-label provides an accessible name directly through an ARIA attribute.
<button
type="button"
aria-label="Close dialog">
×
</button>
This can be useful when the visible content of a control does not adequately communicate its purpose.
Do not add aria-label unnecessarily when a visible, meaningful label already provides the accessible name.
17. aria-labelledby
aria-labelledby associates an element with another element that provides its accessible name.
<h2 id="dialog-title">
Delete Account
</h2>
<div
role="dialog"
aria-labelledby="dialog-title">
<p>
Are you sure you want to continue?
</p>
</div>
The value of aria-labelledby references the id of the naming element.
18. aria-describedby
aria-describedby connects a control with additional descriptive information.
<label for="password">
Password
</label>
<input
type="password"
id="password"
aria-describedby="password-help">
<p id="password-help">
Password must contain at least 8 characters.
</p>
The label identifies the control, while the description provides additional instructions.
19. ARIA States and Properties
ARIA attributes can communicate additional information about an element's current state or characteristics.
| Attribute | Purpose |
|---|---|
| aria-expanded | Indicates whether a controlled expandable region is expanded. |
| aria-hidden | Indicates whether content is hidden from the accessibility tree. |
| aria-current | Identifies the current item in a set or navigation context. |
| aria-selected | Indicates the selected state of an applicable widget item. |
| aria-checked | Communicates the checked state of applicable custom controls. |
| aria-disabled | Communicates a disabled state for applicable widgets. |
20. aria-expanded
This attribute communicates whether an expandable interface element is currently expanded or collapsed.
<button
type="button"
aria-expanded="false"
aria-controls="course-menu">
Courses
</button>
<div id="course-menu" hidden>
<a href="/html">HTML</a>
<a href="/css">CSS</a>
</div>
When the menu opens, the state should be updated:
aria-expanded="true"
ARIA states must reflect the actual state of the interface. Adding an attribute without implementing the corresponding behavior does not make a widget accessible.
21. aria-controls
aria-controls identifies the element controlled by an interactive element.
<button
type="button"
aria-controls="details"
aria-expanded="false">
Show Details
</button>
<div id="details" hidden>
Additional information.
</div>
22. aria-hidden
aria-hidden="true" indicates that an element should be hidden from the accessibility tree.
<span aria-hidden="true">
★
</span>
This can be appropriate when a decorative symbol should not be announced separately by assistive technology.
Do not use aria-hidden to hide content that keyboard users or assistive-technology users still need to access.
23. aria-live
Dynamic content can change without causing the page to reload. ARIA live regions can communicate certain dynamic updates to assistive technologies.
<div
aria-live="polite"
id="status">
</div>
For example, a status message might be updated after a form submission:
<div
aria-live="polite"
id="status">
Form submitted successfully.
</div>
Live regions should be used carefully. Excessive announcements can overwhelm users.
24. Why Custom Controls Are Difficult
Consider this custom control:
<div
role="button"
tabindex="0">
Submit
</div>
Simply adding role="button" does not automatically provide all the behavior of a native button.
A developer may also need to implement appropriate keyboard behavior, focus behavior, state communication and interaction logic.
Preferred Approach
<button type="button">
Submit
</button>
If native HTML can perform the job, use native HTML.
25. ARIA Does Not Automatically Add Functionality
ARIA communicates semantics, states and properties. It does not automatically implement the JavaScript behavior required by a custom widget.
<div
role="button"
aria-expanded="false"
tabindex="0">
Menu
</div>
The developer must still ensure that the control can actually be operated correctly using the keyboard and pointer and that its ARIA state changes when its actual state changes.
26. Accessible Navigation
Use the semantic <nav> element for major navigation areas.
<nav aria-label="Main navigation">
<ul>
<li>
<a href="/">Home</a>
</li>
<li>
<a href="/courses">Courses</a>
</li>
<li>
<a href="/contact">Contact</a>
</li>
</ul>
</nav>
The accessible label can distinguish multiple navigation landmarks when necessary.
27. Identify the Current Page
The aria-current attribute can identify the current item within a set.
<nav aria-label="Main navigation">
<a href="/html">
HTML
</a>
<a
href="/css"
aria-current="page">
CSS
</a>
</nav>
28. Accessible Tables
Tables should use appropriate table semantics.
<table>
<caption>
Course Schedule
</caption>
<thead>
<tr>
<th scope="col">
Course
</th>
<th scope="col">
Duration
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
HTML
</td>
<td>
8 Weeks
</td>
</tr>
</tbody>
</table>
Proper table structure helps assistive technologies interpret relationships between headers and data cells.
29. Prefer Native Interactive Elements
HTML provides several native interactive elements that can reduce the need for custom ARIA implementations.
<details>
<summary>
What is HTML?
</summary>
<p>
HTML is the standard markup language for structuring
webpages.
</p>
</details>
Native elements often provide built-in semantics and interaction behavior that would otherwise require additional scripting.
30. Dialog Accessibility
Modern HTML includes the native <dialog> element for dialog interfaces.
<dialog id="help-dialog">
<h2>Help</h2>
<p>
Find answers to frequently asked questions.
</p>
<form method="dialog">
<button>
Close
</button>
</form>
</dialog>
Native controls and elements should be considered before creating a completely custom ARIA widget.
31. Do Not Communicate Meaning Through Color Alone
Information should not depend exclusively on color.
Poor Approach
<p>
<span class="status-green">Approved</span>
</p>
Better Approach
<p>
Status:
<strong>Approved</strong>
</p>
Color may supplement meaning, but important information should remain understandable without relying on color alone.
32. Do Not Use Placeholder as the Only Label
A placeholder is temporary instructional text and should not normally replace a proper form label.
Poor Example
<input
type="email"
placeholder="Enter email">
Better Example
<label for="email">
Email Address
</label>
<input
type="email"
id="email"
name="email"
placeholder="name@example.com">
33. Accessible Form Errors
Error messages should clearly explain what went wrong and, where appropriate, be associated with the affected control.
<label for="email">
Email Address
</label>
<input
type="email"
id="email"
aria-invalid="true"
aria-describedby="email-error">
<p id="email-error">
Enter a valid email address.
</p>
Here, aria-invalid="true" communicates that the current value has failed validation, while aria-describedby associates the error explanation with the control.
34. Complete Accessible HTML Structure
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta
name="viewport"
content="width=device-width, initial-scale=1.0">
<title>Accessible HTML Tutorial</title>
</head>
<body>
<header>
<nav aria-label="Main navigation">
<a href="/">Home</a>
<a href="/courses">Courses</a>
<a href="/contact">Contact</a>
</nav>
</header>
<main>
<article>
<h1>HTML Accessibility</h1>
<section>
<h2>Semantic HTML</h2>
<p>
Semantic HTML provides meaningful structure
for users and assistive technologies.
</p>
</section>
<section>
<h2>Accessible Forms</h2>
<form>
<label for="name">
Name
</label>
<input
type="text"
id="name"
name="name"
required>
<button type="submit">
Submit
</button>
</form>
</section>
</article>
</main>
<footer>
<p>
Accessible Web Learning
</p>
</footer>
</body>
</html>
35. How to Test HTML Accessibility
Test 1 — Keyboard Only
- Disconnect or avoid the mouse.
- Press Tab repeatedly.
- Check whether focus moves logically.
- Activate links and buttons.
- Open and close interactive components.
- Ensure no important functionality is inaccessible.
Test 2 — Screen Reader
Test important pages with a screen reader where possible. Check headings, landmarks, links, buttons, form labels and dynamic messages.
Test 3 — Automated Tools
Automated accessibility tools can identify many common issues, but they cannot detect every accessibility problem.
Use automated testing together with manual keyboard, interaction and assistive-technology testing.
36. Common Accessibility Mistakes
| Mistake | Better Approach |
|---|---|
| Using div instead of button | Use a native button. |
| Images without meaningful alternatives | Provide appropriate alt text. |
| Inputs without labels | Use properly associated labels. |
| Removing focus indicators | Maintain a visible focus indication. |
| Using color as the only indicator | Provide additional text or semantic information. |
| Using ARIA unnecessarily | Prefer native HTML semantics. |
| Incorrect ARIA state | Keep ARIA state synchronized with actual UI state. |
| Positive tabindex values | Prefer natural document order and tabindex="0" only when appropriate. |
37. Interview Questions
1. What is web accessibility?
View Answer
Web accessibility means designing websites so that people with different abilities can perceive, understand, navigate and interact with web content.
2. What does ARIA stand for?
View Answer
ARIA stands for Accessible Rich Internet Applications.
3. What is the purpose of ARIA?
View Answer
ARIA provides additional semantic information, including roles, states and properties, to assistive technologies, especially for dynamic or custom interfaces.
4. Should ARIA be used instead of semantic HTML?
View Answer
Generally, no. Native semantic HTML should be preferred whenever it provides the required functionality. ARIA is used when additional semantics are necessary.
5. What is the difference between aria-label and aria-labelledby?
View Answer
aria-label directly provides an accessible name, while aria-labelledby references another element whose content provides the accessible name.
6. What is aria-describedby used for?
View Answer
It associates an element with additional descriptive information, such as instructions, help text or an error message.
7. What is the difference between a button and a link?
View Answer
A link normally navigates to a resource or URL, whereas a button normally performs an action.
8. Why is keyboard accessibility important?
View Answer
Some users cannot operate a mouse and depend on keyboard navigation to access and operate website functionality.
38. Exam Questions
Q1. What is ARIA?
Answer
ARIA is a set of attributes known as Accessible Rich Internet Applications that provides additional accessibility semantics for user-interface elements.
Q2. Write the HTML code for an accessible form field.
Answer
<label for="username">
Username
</label>
<input
type="text"
id="username"
name="username">
Q3. Differentiate between aria-label and aria-labelledby.
Answer
aria-label directly specifies an accessible name, whereas aria-labelledby references another element that provides the accessible name.
Q4. Why should semantic HTML be preferred over unnecessary ARIA?
Answer
Native semantic elements already provide standardized semantics, keyboard behavior and browser/assistive technology support. Custom ARIA implementations can introduce additional complexity and accessibility errors.
Q5. What is the purpose of alt text?
Answer
Alt text provides a text alternative for informative images so their relevant meaning can be communicated to users who cannot perceive the image.
Q6. What does aria-expanded indicate?
Answer
It communicates whether an associated expandable interface element is currently expanded or collapsed.
39. Practical Task
Create an accessible course registration webpage.
Your page must contain:
- A semantic header and navigation.
- A main content area.
- A properly structured heading hierarchy.
- An accessible registration form.
- Labels associated with every form control.
- A grouped set of radio buttons using fieldset and legend.
- A meaningful image with alt text.
- Keyboard-accessible buttons and links.
- An accessible error-message example.
- A footer.
Advanced Challenge
Build a custom expandable course menu using a button, aria-expanded and aria-controls. Use JavaScript to ensure that the ARIA state always matches the actual state of the menu.
40. Quick Revision
| Concept | Remember |
|---|---|
| Accessibility | Making websites usable by people with different abilities. |
| Semantic HTML | Use elements according to their meaning. |
| ARIA | Accessible Rich Internet Applications. |
| role | Communicates the purpose/type of an interface element. |
| aria-label | Provides an accessible name directly. |
| aria-labelledby | Uses another element as the accessible name. |
| aria-describedby | Associates additional descriptive information. |
| aria-expanded | Communicates expanded/collapsed state. |
| aria-controls | Identifies a controlled element. |
| aria-hidden | Hides content from the accessibility tree. |
| aria-live | Communicates certain dynamic updates. |
| alt | Provides an alternative text representation for informative images. |
| Keyboard Access | Essential functionality should be operable without a mouse. |
| Native HTML | Prefer native controls before creating custom ARIA widgets. |
Use semantic HTML first. Add ARIA only when necessary. Make every important interaction keyboard accessible, provide meaningful names and descriptions, and test the actual user experience.