HTML and CSS course Β· Module 10: Accessibility (a11y)
ARIA - Accessible Rich Internet Applications
In this lesson6
ARIA (Accessible Rich Internet Applications) is a set of HTML attributes that help make dynamic content and advanced interfaces accessible to assistive technologies. You can think of ARIA as additional hieroglyphs on a temple wall - they add meaning where HTML alone is not sufficient.
The First Rule of ARIA
Do not use ARIA if you can use native HTML!
1<!-- BAD - ARIA on a div -->
2<div role="button" tabindex="0" aria-pressed="false">Click me</div>
3
4<!-- GOOD - native HTML -->
5<button>Click me</button>A native <button> is automatically focusable, responds to Enter and Space, and is recognized by screen readers. Use ARIA only when native HTML does not offer the needed functionality.
ARIA Roles
Roles define what an element is in the context of the interface.
1<!-- Landmark roles -->
2<div role="banner">Page header</div>
3<div role="navigation">Navigation</div>
4<div role="main">Main content</div>
5<div role="complementary">Sidebar</div>
6<div role="contentinfo">Footer</div>
7
8<!-- Widget roles -->
9<div role="tablist">
10 <button role="tab" aria-selected="true">Tab 1</button>
11 <button role="tab" aria-selected="false">Tab 2</button>
12</div>
13<div role="tabpanel">Tab content</div>
14
15<!-- Alert role -->
16<div role="alert">An error occurred! Check the form.</div>ARIA States & Properties
aria-label
Gives an element an invisible text label.
1<!-- Button with icon - no visible text -->
2<button aria-label="Close dialog">
3 <span class="icon">X</span>
4</button>
5
6<!-- Navigation with label -->
7<nav aria-label="Exhibition navigation">
8 <ul>...</ul>
9</nav>aria-describedby
Links an element with an additional description.
1<label for="password">Password:</label>
2<input type="password" id="password"
3 aria-describedby="password-help">
4<p id="password-help">
5 Password must have at least 8 characters, an uppercase letter, and a number.
6</p>aria-hidden
Hides an element from screen readers (but it remains visually visible).
1<!-- Decorative icon - hidden from reader -->
2<button>
3 <span aria-hidden="true" class="icon">☰</span>
4 Menu
5</button>
6
7<!-- NOTE: Never hide content that is important! -->aria-live
Informs the screen reader about dynamic changes on the page.
1<!-- Live region - reader will announce changes -->
2<div aria-live="polite" id="status">
3 <!-- Content updated dynamically -->
4</div>
5
6<!-- Urgent notification -->
7<div aria-live="assertive" role="alert">
8 Session will expire in 2 minutes!
9</div>Values of aria-live:
off- no announcements (default)polite- will wait until the reader finishes the current sentenceassertive- will interrupt current reading immediately
aria-expanded
Informs about the state of expandable elements.
1<button aria-expanded="false" aria-controls="menu">
2 Navigation Menu
3</button>
4<nav id="menu" hidden>
5 <ul>
6 <li><a href="/">Home</a></li>
7 <li><a href="/exhibitions">Exhibitions</a></li>
8 </ul>
9</nav>aria-required and aria-invalid
Form validation.
1<label for="name">Name (required):</label>
2<input type="text" id="name"
3 aria-required="true"
4 aria-invalid="false">
5
6<!-- After failed validation -->
7<input type="email" id="email"
8 aria-required="true"
9 aria-invalid="true"
10 aria-describedby="email-error">
11<p id="email-error" role="alert">
12 Please enter a valid email address.
13</p>ARIA Summary
Remember the five rules of ARIA:
- Do not use ARIA if you can use native HTML
- Do not change the semantics of native elements - do not add
role="heading"to<p> - All interactive ARIA elements must be keyboard accessible
- Do not use
aria-hidden="true"on focusable elements - All interactive elements must have an accessible name
Testing ARIA
To check if your ARIA attributes work correctly:
- Screen reader - use VoiceOver (Mac), NVDA (Windows), or TalkBack (Android)
- Chrome DevTools - the Accessibility tab shows the accessibility tree
- Extensions - axe DevTools, WAVE
Practical Test
Open a page, turn off the monitor (or close your eyes), and try navigating it using only the keyboard and a screen reader. Is all the information accessible? Do you know what each button does?
ARIA Checklist for Developers
- Does every interactive element have an accessible name (text, aria-label)?
- Are dynamic changes on the page announced via aria-live?
- Do modal dialogs have proper focus trap?
- Are states (expanded, selected, pressed) being updated?
- Do decorative elements have aria-hidden="true"?
ARIA is a powerful tool in the hands of an accessibility builder - like magical amulets that give elements hidden power understood by screen readers. But just like amulets in Egyptian temples, they must be used with knowledge and moderation. Too much ARIA can do more harm than good!
Code for this lesson: index.html
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <title>ARIA - Accessibility attributes</title>
7 <link rel="stylesheet" href="style.css">
8</head>
9<body>
10 <h1>ARIA in practice</h1>
11
12 <!-- aria-label -->
13 <section>
14 <h2>aria-label - an invisible label</h2>
15 <button aria-label="Close dialog" class="icon-btn">
16 <span aria-hidden="true">✕</span>
17 </button>
18 <p>A button with an X icon - the reader will say "Close dialog"</p>
19 </section>
20
21 <!-- aria-describedby -->
22 <section>
23 <h2>aria-describedby - an additional description</h2>
24 <label for="pwd">Password:</label>
25 <input type="password" id="pwd" aria-describedby="pwd-help">
26 <p id="pwd-help" class="hint">
27 At least 8 characters, a capital letter and a digit.
28 </p>
29 </section>
30
31 <!-- aria-expanded -->
32 <section>
33 <h2>aria-expanded - expandable state</h2>
34 <button aria-expanded="false"
35 aria-controls="faq-answer"
36 onclick="toggleFaq(this)">
37 What is a scarab?
38 </button>
39 <div id="faq-answer" hidden>
40 <p>The scarab is a sacred beetle of Ancient Egypt,
41 symbolizing rebirth and the sun god Khepri.</p>
42 </div>
43 </section>
44
45 <!-- aria-live -->
46 <section>
47 <h2>aria-live - dynamic notifications</h2>
48 <button onclick="updateStatus()">Check ticket availability</button>
49 <div aria-live="polite" id="ticket-status" class="status">
50 Click the button to check.
51 </div>
52 </section>
53
54 <!-- role="alert" -->
55 <section>
56 <h2>role="alert" - an urgent notification</h2>
57 <button onclick="showAlert()">Show alert</button>
58 <div id="alert-area"></div>
59 </section>
60
61 <script>
62 function toggleFaq(btn) {
63 const expanded = btn.getAttribute('aria-expanded') === 'true';
64 btn.setAttribute('aria-expanded', !expanded);
65 document.getElementById('faq-answer').hidden = expanded;
66 }
67
68 function updateStatus() {
69 document.getElementById('ticket-status').textContent =
70 '15 tickets available for the Treasures of Tutankhamun exhibition.';
71 }
72
73 function showAlert() {
74 const area = document.getElementById('alert-area');
75 area.innerHTML = '<div role="alert" class="alert">' +
76 'Attention! The exhibition closes in 30 minutes.</div>';
77 }
78 </script>
79</body>
80</html>Spotted a mistake in this lesson?
Check yourself
Answer the questions from this lesson. Pick an answer to see right away whether it is correct.
1. What is the first rule of using ARIA?
2. What is the difference between aria-live="polite" and aria-live="assertive"?
These are 2 of 3 questions for this lesson. Solve the rest in the game.
Hands-on tasks in the game
- Horizontal ordering
Arrange the correct syntax of a field with aria-describedby:
- Code editor
Add ARIA attributes: aria-label to an icon button, aria-describedby to a search field, aria-hidden to a decorative icon, and aria-expanded with aria-controls to a FAQ section.