Skip to content

Commit 958fb2b

Browse files
authored
feat(curriculum): Add interactive examples to aria roles lesson (freeCodeCamp#63790)
1 parent dfe7279 commit 958fb2b

1 file changed

Lines changed: 347 additions & 2 deletions

File tree

curriculum/challenges/english/blocks/lecture-introduction-to-aria/672a549231b8728f7171ed9d.md

Lines changed: 347 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ challengeType: 19
55
dashedName: what-are-aria-roles
66
---
77

8-
# --description--
8+
# --interactive--
9+
10+
**NOTE**: Some of these interactive examples might include CSS and JavaScript code. Don't worry about trying to understand the code. The previews are there to help illustrate some of the main points discussed in the lesson. To see the previews, you will need to enable the interactive editor.
911

1012
ARIA stands for Accessible Rich Internet Applications.
1113

@@ -15,11 +17,57 @@ HTML has semantic and non-semantic elements, based on whether they convey meanin
1517

1618
Many semantic HTML elements already have an ARIA role assigned by default. For example, the `button` element has a default ARIA role of `button`.
1719

20+
:::interactive_editor
21+
22+
```html
23+
<button>Example button</button>
24+
```
25+
26+
:::
27+
1828
But non-semantic elements don't have a role. For example, screen readers will not know how to interpret the purpose of a `div` if you don't specify its role explicitly.
1929

30+
```html
31+
<div>
32+
<!-- more elements go here -->
33+
</div>
34+
```
35+
2036
To specify the ARIA role of an element, you just need to add the `role` attribute, like this `role="ARIA role"`, where value is the name of a role in the ARIA specification.
2137

22-
It is important to note that specifying a role on an element only does one thing: It informs assistive technology of the purpose of the element. It does not add any functionality or behavior to the element. If people expect a role to behave a certain way, it is up to you, the developer, to add that expected behavior. For example, adding a `role` of `button` to a `div` does not automatically make it clickable with a mouse or usable with a keyboard. It is the responsibility of the developer to add the expected behavior that allows the `div` to act like a button, and in most cases, it is just better to use the `button` element.
38+
Here is an example of using the `role` attribute with a value of `"alert"`:
39+
40+
:::interactive_editor
41+
42+
```html
43+
<link rel="stylesheet" href="styles.css">
44+
45+
<div class="alert" id="exp-warning" role="alert">
46+
<span class="hidden">Your log in session will expire in 3 minutes.</span>
47+
</div>
48+
```
49+
50+
```css
51+
.alert {
52+
background-color: #fff3cd;
53+
border: 1px solid #ffeeba;
54+
color: #856404;
55+
padding: 1em;
56+
margin-top: 1em;
57+
border-radius: 4px;
58+
font-weight: bold;
59+
}
60+
61+
.alert span {
62+
display: inline-block;
63+
}
64+
```
65+
66+
:::
67+
68+
It is important to note that specifying a role on an element only does one thing: It informs assistive technology of the purpose of the element. It does not add any functionality or behavior to the element. If people expect a role to behave a certain way, it is up to you, the developer, to add that expected behavior.
69+
70+
For example, adding a `role` of `button` to a `div` does not automatically make it clickable with a mouse or usable with a keyboard. It is the responsibility of the developer to add the expected behavior that allows the `div` to act like a button, and in most cases, it is just better to use the `button` element.
2371

2472
There are six main categories of ARIA roles:
2573

@@ -40,26 +88,323 @@ You should specify the roles that don't have an equivalent semantic element. For
4088

4189
There are other similar roles but these are the most commonly used ones. This is an example of a `div` with the `math` ARIA role. The `div` contains a mathematical equation.
4290

91+
:::interactive_editor
92+
4393
```html
94+
<link rel="stylesheet" href="styles.css">
95+
4496
<div role="math" aria-label="x squared + y squared = 3">
4597
x<sup>2</sup> + y<sup>2</sup> = 3
4698
</div>
4799
```
48100

101+
```css
102+
.math-expression {
103+
font-family: "Times New Roman", serif;
104+
font-size: 1.2rem;
105+
background-color: #f4f4f4;
106+
border-left: 4px solid #007acc;
107+
padding: 0.75em 1em;
108+
margin-top: 1em;
109+
display: inline-block;
110+
}
111+
112+
.math-expression sup {
113+
font-size: 0.8em;
114+
}
115+
```
116+
117+
:::
118+
49119
You'll also notice that the `div` has an `aria-label` attribute. The value of this attribute should be a string that represents the expression.
50120

51121
Widget roles define the purpose and functionality of interactive elements, like scrollbars.
52122

53123
Examples of widget roles include `scrollbar`, `searchbox`, `separator` (when focusable), `slider`, `spinbutton`, `switch`, `tab`, `tabpanel`, and `treeitem`.
54124

125+
Here is an example of a searchbox:
126+
127+
:::interactive_editor
128+
129+
```html
130+
<link rel="stylesheet" href="styles.css">
131+
132+
<div class="search-container" role="search">
133+
<label for="searchbox" class="visually-hidden">Search</label>
134+
135+
<div
136+
id="searchbox"
137+
class="searchbox"
138+
role="searchbox"
139+
aria-label="Search the site"
140+
tabindex="0"
141+
contenteditable="true">
142+
</div>
143+
144+
<button type="button" aria-label="Submit search">Search</button>
145+
</div>
146+
147+
```
148+
149+
```css
150+
.search-container {
151+
display: flex;
152+
align-items: center;
153+
gap: 0.5em;
154+
margin-top: 1em;
155+
}
156+
157+
.searchbox {
158+
flex: 1;
159+
padding: 0.5em;
160+
border: 1px solid #ccc;
161+
border-radius: 4px;
162+
font-size: 1em;
163+
min-height: 1.5em;
164+
}
165+
166+
.searchbox:focus {
167+
border-color: #007acc;
168+
outline: none;
169+
box-shadow: 0 0 0 2px rgba(0, 122, 204, 0.3);
170+
}
171+
172+
button {
173+
padding: 0.5em 1em;
174+
background-color: #007acc;
175+
color: #fff;
176+
border: none;
177+
border-radius: 4px;
178+
cursor: pointer;
179+
}
180+
181+
button:hover {
182+
background-color: #005fa3;
183+
}
184+
185+
/* Hide visually but keep for screen readers */
186+
.visually-hidden {
187+
position: absolute;
188+
left: -9999px;
189+
}
190+
```
191+
192+
:::
193+
55194
Some of these roles have equivalent semantic elements. You should prioritize the semantic element over the role if there is one. For example, you should favor using the HTML `button` element over adding a `role` of `button` to a `div`.
56195

57196
Landmark roles classify and label the primary sections of a web page. Screen readers use them to provide convenient navigation to important sections of a page. You should use them sparingly to keep the overall layout simple and easy to understand. Examples of landmark roles are `banner`, `complementary`, `contentinfo`, `form`, `main`, `navigation`, `region`, and `search`. Each of these roles has a corresponding HTML equivalent, such as `header`, `footer`, `aside`, `form`, `main`, `nav`, `section`, and `search`. If you use the proper HTML elements to define the sections of your page then it is not necessary to explicitly add the `role` attribute to these elements.
58197

198+
Here is an example of a banner:
199+
200+
:::interactive_editor
201+
202+
```html
203+
<link rel="stylesheet" href="styles.css">
204+
205+
206+
<div role="banner" class="site-banner">
207+
<h1>Accessible Web Design</h1>
208+
<nav>
209+
<ul>
210+
<li><a href="#">Home</a></li>
211+
<li><a href="#">Articles</a></li>
212+
<li><a href="#">About</a></li>
213+
<li><a href="#">Contact</a></li>
214+
</ul>
215+
</nav>
216+
</div>
217+
```
218+
219+
```css
220+
.site-banner {
221+
background-color: #007acc;
222+
color: #fff;
223+
padding: 1em 1.5em;
224+
border-radius: 4px;
225+
}
226+
227+
.site-banner h1 {
228+
margin: 0 0 0.5em;
229+
font-size: 1.5em;
230+
}
231+
232+
.site-banner nav ul {
233+
list-style: none;
234+
margin: 0;
235+
padding: 0;
236+
display: flex;
237+
gap: 1em;
238+
}
239+
240+
.site-banner nav a {
241+
color: #fff;
242+
text-decoration: none;
243+
font-weight: 500;
244+
}
245+
246+
.site-banner nav a:hover {
247+
text-decoration: underline;
248+
}
249+
```
250+
251+
:::
252+
59253
Live region roles define elements with content that will change dynamically. This way, screen readers and other assistive technologies can announce changes to users with visual disabilities. These roles include: `alert`, `log`, `marquee`, `status`, and `timer`.
60254

255+
Here is an example of a status:
256+
257+
:::interactive_editor
258+
259+
```html
260+
<link rel="stylesheet" href="styles.css">
261+
262+
<div class="status-demo">
263+
<button id="update-status-btn">Check Status</button>
264+
<div id="status-msg" role="status" class="status-message">
265+
No updates yet.
266+
</div>
267+
</div>
268+
269+
<script src="index.js"></script>
270+
```
271+
272+
```css
273+
.status-demo {
274+
margin-top: 1em;
275+
}
276+
277+
button {
278+
padding: 0.5em 1em;
279+
background-color: #007acc;
280+
color: #fff;
281+
border: none;
282+
border-radius: 4px;
283+
cursor: pointer;
284+
}
285+
286+
button:hover {
287+
background-color: #005fa3;
288+
}
289+
290+
.status-message {
291+
margin-top: 0.75em;
292+
padding: 0.75em;
293+
background-color: #e8f4ff;
294+
border: 1px solid #b3d8ff;
295+
border-radius: 4px;
296+
font-weight: 500;
297+
}
298+
```
299+
300+
```js
301+
const button = document.getElementById("update-status-btn");
302+
const statusMessage = document.getElementById("status-msg");
303+
304+
button.addEventListener("click", () => {
305+
statusMessage.textContent = "Your upload has completed successfully.";
306+
});
307+
```
308+
309+
:::
310+
61311
Window roles define sub-windows, like pop up modal dialogues. These roles include `alertdialog` and `dialog`. Please note that it is now considered a best practice to use the HTML `dialog` element and its associated JavaScript methods instead of manually creating a dialog.
62312

313+
Here is an example of using a `dialog` role for a custom dialog:
314+
315+
:::interactive_editor
316+
317+
```html
318+
<link rel="stylesheet" href="styles.css">
319+
320+
<button id="open-dialog">Open Dialog</button>
321+
322+
<div id="custom-dialog" role="dialog" aria-modal="true" aria-labelledby="dialog-title" class="dialog">
323+
<div class="dialog-content">
324+
<h3 id="dialog-title">Confirm Action</h3>
325+
<p>Are you sure you want to delete this file?</p>
326+
<div class="dialog-actions">
327+
<button id="confirm-btn">Yes</button>
328+
<button id="close-dialog">Cancel</button>
329+
</div>
330+
</div>
331+
</div>
332+
333+
<script src="index.js"></script>
334+
```
335+
336+
```css
337+
body {
338+
font-family: Arial, sans-serif;
339+
margin: 2em;
340+
}
341+
342+
button {
343+
padding: 0.5em 1em;
344+
border: none;
345+
border-radius: 4px;
346+
cursor: pointer;
347+
background-color: #007acc;
348+
color: white;
349+
font-size: 1em;
350+
}
351+
352+
button:hover {
353+
background-color: #005fa3;
354+
}
355+
356+
.dialog {
357+
display: none;
358+
position: fixed;
359+
top: 0;
360+
left: 0;
361+
width: 100%;
362+
height: 100%;
363+
background-color: rgba(0, 0, 0, 0.5);
364+
justify-content: center;
365+
align-items: center;
366+
z-index: 1000;
367+
}
368+
369+
.dialog-content {
370+
background-color: white;
371+
padding: 1.5em;
372+
border-radius: 8px;
373+
width: 90%;
374+
max-width: 400px;
375+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
376+
}
377+
378+
.dialog-actions {
379+
display: flex;
380+
justify-content: flex-end;
381+
gap: 0.5em;
382+
margin-top: 1em;
383+
}
384+
```
385+
386+
```js
387+
const dialog = document.getElementById("custom-dialog");
388+
const openBtn = document.getElementById("open-dialog");
389+
const closeBtn = document.getElementById("close-dialog");
390+
const confirmBtn = document.getElementById("confirm-btn");
391+
392+
openBtn.addEventListener("click", () => {
393+
dialog.style.display = "flex";
394+
});
395+
396+
closeBtn.addEventListener("click", () => {
397+
dialog.style.display = "none";
398+
});
399+
400+
confirmBtn.addEventListener("click", () => {
401+
alert("File deleted.");
402+
dialog.style.display = "none";
403+
});
404+
```
405+
406+
:::
407+
63408
And finally, we have abstract roles. These roles help organize the document. They're only meant to be used internally by the browser, not by developers, so you should know that they exist but you shouldn't use them on your websites or web applications.
64409

65410
With ARIA roles, you can create accessible and inclusive websites and web applications. They provide semantic information about the purpose and function of HTML elements.

0 commit comments

Comments
 (0)