Create a Semantic Checkbox vs an ARIA Checkbox

Lindsey Kopacz
InstructorLindsey Kopacz
Share this video with your friends

Social Share Links

Send Tweet

We'll go over the work it takes to use ARIA to show why Semantic HTML is almost always the safer bet.

Instructor: [0:00] Let's create two separate examples of checkboxes. First, we'll create a basic checkbox, input-type checkbox. We'll add an ID of checkbox 1. Then, we'll create a label and associate it with the checkbox, so checkbox-1 in the for attribute and then the label name will be checkbox 1.

[0:21] Then, to clean this up, we'll create a div with a class of Semantic example. We will wrap that div around this checkbox. Next, let's create a div with a class of ARIA example. Instead of using Semantic HTML, we're going to use ARIA. First, we'll create a span. We'll give that a role of checkbox.

[0:42] We'll give it an ARIA checked attribute, and we'll make that false. Then, we'll give it a tab index of zero. After that, we'll create a label. Instead of a for attribute, we'll add an ID attribute. We'll make that id checkbox-2.

[0:59] Back on that span, we'll add an ARIA labeled by equals checkbox-2. It looks like I forgot to actually add a label, so we'll give that label text checkbox-2.

[1:14] If we go back to the browser, you'll see that we have a checkbox-2, but there is not an actual checkbox. If we inspect this element, and we click on that span and go to the accessibility dev tools, you'll see under the computed properties, we have a name of checkbox-2 that's provided by the label.

[1:32] The role is checkbox. It's focusable because we added that tab index. Then, we have checked is false. That check state is created by the ARIA checked false. Now if we go to the semantic example, you'll see that it looks pretty similar. The computed properties, we have a name of checkbox-1.

[1:50] We have a role of checkbox. It's focusable and the check state is also false. I wanted to point this out because the API looks incredibly similar when we use this ARIA attribute. As you can see, the checkbox-1, if you click on it, the state changes, but nothing changes about checkbox-2. We don't even have any styling or an actual checkbox.

[2:10] Let's go ahead and try to make this span look somewhat like a checkbox. Inside the head, we're just going to add some style tags. Inside the style tags, I'm going to use the role attribute to style. We'll do a display of inline block, height 10 pixels, width 10 pixels. We'll do border one pixel solid.

[2:34] Now, it looks somewhat like a checkbox, but we still don't have a state. Now, we have to create a bunch of JavaScript to make this work like a checkbox. On the bottom of the body tag, we'll add some script tags. First, we'll create a variable called ARIA checkboxes.

[2:48] Then, we'll do document.querySelectorall(role=checkbox), just to make sure that that is printing out correctly, ARIA checkboxes. Let's go to the console. We see that we have that span. Let's get rid of this console log.

[3:04] Now next, what we have to do is we have to loop through all those ARIA checkboxes. ARIA checkboxes for each in the callback, I'm going to pass in checkbox as the parameter. For every checkbox, you want to add an event listener, and we'll add a click listener.

[3:21] Inside that click listener, we want to make sure we get the state of isChecked. We'll take the checkbox, get attribute aria-checked, and we'll make this a simple ternary. If aria-checked=string "true" because that's what it will return, not a Boolean, then we'll return true, otherwise false.

[3:42] Then, we'll do checkbox set attribute aria checked, and then we'll do the opposite of is. Before we test this out, we want to actually make sure we give some styling so we can easily see if that checked is working without looking at the dev tools.

[3:58] We'll do role=checkbox, and then aria-checked=true. Then, we'll just make it simple and give it a background color. Now, if we refresh this, you'll see that if we click on it, it works.

[4:17] The one thing that's different is, if we press the tab key and focus on the first checkbox, so this is a semantic checkbox, we press the space key, it does check, but now if we focus on that span, nothing happens.

[4:29] Now, we have to add that key up listener. Go back to the JavaScript, and inside this for each, we'll add another listener, checkbox.addEventListener, key up. We want to make sure we pass the event. I'm going to just go ahead and copy and paste "isChecked.

[4:45] Next, we want to check if eventcode=space, and we want to specify the space bar because we don't want to have this trigger on any old key, only the space bar. We are going to copy and paste this code again.

[4:59] Now, if we refresh this and we tab tab, you'll see that this works. The reason to go over this is because I wanted to show you that you could essentially do the same thing with ARIA. However, you have to do a lot of CSS and JavaScript work to make it functional.

[5:13] Additionally, if we add custom functionality, that means we have to write additional tests. In this example, we haven't even accounted for touch listeners on mobile. It's extra work we would have to do.

[5:22] We also don't know what the support is on other assistive technologies and how good it is. We always want to default to the semantic HTML, where possible.