Check out a free preview of the full Enterprise Web App Accessibility (feat. React) course:
The "Buttons, Links, & Div Accessibility" Lesson is part of the full, Enterprise Web App Accessibility (feat. React) course featured in this preview video. Here's what you'd learn in this lesson:

Marcy explains that buttons are used for toggling things, submitting forms, and interacting with the page. The instructor also emphasizes the importance of using buttons and links appropriately, as well as the potential confusion that can arise if they are not used correctly. They provide examples and tips for making buttons accessible and discuss the potential pitfalls of using divs with click events instead of buttons. The lesson also touches on the role of AI in accessibility and the need for developers to take responsibility for creating accessible interfaces.

Get Unlimited Access Now

Transcript from the "Buttons, Links, & Div Accessibility" Lesson

[00:00:00]
>> We're gonna talk about buttons a whole lot more, way more than you probably wanted to know about buttons. So buttons are for toggling things. Like you have a setting in your user interface, you're gonna make a button. They're also for forms. They submit forms, they might toggle other features in forms.

[00:00:18] You have button or button types submit. So they're meant for interacting with the page, whereas links are for navigation. So we wanna use links with href attributes for navigating. Sometimes, with JavaScript, everything's a hammer, and it's really odd. You have a hammer, and everything's a nail, and you can just bend it to your will.

[00:00:40] But for users, it can be confusing when everything is a link or a button, and we're not really intentional with the semantic purpose of those. So links navigate, buttons toggle things. Buttons are for interactive things, which we have quite a few use cases for, and sometimes it can vary, like, is your modal deep linked?

[00:01:01] If it's deep linked, then you're gonna need to launch it with a link that has a href and a URL. But if it's just like a stateful change that doesn't have a link attached to it, or an endpoint that the user can get to, then a button's probably fine.

[00:01:17] Cuz you're gonna launch something, you hit refresh, and it's not gonna persist. So sometimes it can depend on what you're doing with it. Like, does it have a link or not? So yeah, that's kind of like setting the scene for links versus buttons. But when there are buttons in the code base, we want them to be real buttons, not that div with a click event.

[00:01:39] Cuz like man, nothing pains me more than seeing that in codebases, especially when you can't just rip it out immediately. I'm like, let me add it, let me rip that div button out of there, but you can't always. So my goal in this is to help you spot these before they ship.

[00:01:56] Don't let them ship, and don't ship them yourselves. [LAUGH]. So here's what it takes to make a div into an accessible button. We've got the onClick. All right, we had that already. We have to edit onKeyDown or onKeyUp with a key handler, and we're probably going to have to check the event code off the event object.

[00:02:16] Check if it was the space or the Enter key, then run our logic. That is where you can respond to different keyboard events, like the arrow keys and things. We also, on our div button, we have to add a role of button, and we have to add a tabIndex of zero to make it focusable.

[00:02:33] And the text inside will give it a name or a label. But if it was just a button, we could skip so much of that. It would be so much simpler. We don't have to write that extra handler. We don't have to add a role. We don't have to add tabIndex.

[00:02:48] It's just easier. Now, why do people do this? I don't know. Sometimes, it's the styling, not only the legacy styling that you don't wanna risk changing. Sometimes, people are just kind of lazy, [LAUGH] to be frank. Like, but I have to style it. It's like, well, you're capable of so much.

[00:03:08] You can do that, I hope. I mean, maybe there's some other constraints I don't know about, but get a good button reset so that it's not an issue. Just make it easy to make button elements. To make some good defaults. So be on the lookout for those, cuz they're some of the most pervasive, failures for keyboard accessibility.

[00:03:32] And we're gonna work on one in our exercise, of one that's inspired by a real-world example. And so, yeah, keep an eye out for that. And then, a note about AI here, because I feel like a lot of the conversation lately has been around what can AI do for us?

[00:03:47] How can we get away with fewer engineering resources? Resources or real people. But I think there's kind of this elephant in the room that capitalistic folks, leadership trying to please stakeholders, want to cut costs. And so, AI enters the conversation of like, what can it do for us?

[00:04:10] Can we have the screen readers just figure it out? So we don't have to change our authoring process. We don't have to fix stuff. We'll just let the screen reader figure it out. We can't rely on that. I mean, first of all, we can do better than that.

[00:04:25] I don't think we wanna give up. We aren't free from the requirement of actually making something accessible. But we also can't expect assistive technology or AI to solve it for us. With assistive technology in particular, that's a very fancy piece of software that a lot of people can't afford.

[00:04:46] Or they're on a really old version, they might need a grant, or some sort of government assistance to get that technology. So it's like a pretty privileged point of view to think that AI and assistive tech can just solve it for us. I think, instead, it's good to cover these basics and feel some sense of pride in the fact that we can make stuff that's way more robust at its core.

[00:05:10]
>> So basically, button and anchor tags are equivalent to buttons. Can you clarify what you mean by buttons in quotes? Do you mean in terms of how someone with assistive technologies perceive them, or do you mean by how they look?
>> Both. So there's kind of an overlap here.

[00:05:29] Great question. So we wanna make links look like links and buttons look like buttons as much as possible. When sometimes, our CTAs, I have worked with some that if you pass this button, an href, it'll turn it into a link. But it's a button component. And I think where it gets confusing for users is if you can see the screen, but you're using assistive technology.

[00:05:53] Say, you call into customer support, and they're helping to navigate you through an application. There can be some confusion there about what is this element? And similarly, for voice navigation, kinda like what you see on the screen is how you're gonna know what to tell your voice assistant what to interact with.

[00:06:12] So sometimes, that gap in how something's marked up versus how it looks can have an impact on how people can navigate the site. So it is partly the semantic meaning of the button in the link, but then, also, user expectations. And that can get tricky. Sometimes, this is a battle that I do not win.

[00:06:32] I pick my battles. And sometimes, links are gonna look like buttons. It's not ideal, but I mean, talk about design decisions and user impact. Sometimes we have to weigh the cost of what it takes to totally redesign our CTAs for the user impact. I don't know, it's kind of squishy.

[00:06:53] It's not super clearly defined, and it might not be the highest impact thing that you have to deal with. So I'm putting it out there so that you know to look out for it. But I wouldn't say it's the biggest blocker in the world. Having things like div buttons and links that aren't reachable or operable, I think that would be a way bigger blocker.

[00:07:14]
>> I guess a common pattern that I've seen is links that are just like a slightly more elevated buttons, where it changes the route, but also does like a snippet of business logic. Maybe pinging the database, analytics, tracking, updating the state. Is there a good pattern for that where you still wanna have an hrefs, but just a little bit more like having a function call?

[00:07:37]
>> Yeah, I mean, I think if it's a client-rendered application, we'll talk about a little bit later, you should be able to route it and call logic. Yeah, I'd have to test it directly. But I think if you're not losing stuff to a page refresh, you have some potential of being able to fire click event that calls out to analytics, or fetches something, and using routing.

[00:08:01] I mean, you can use ARIA to change the semantics of something. But, as we'll learn with the rules of ARIA, we wanna try and avoid changing rules after the fact. We wanna use the default semantic thing first, if at all possible.
>> So I had a question about, I guess, when you're trying to get a little bit fancier, and you're trying to sort of balance accessibility concerns against, I guess, event bubbling.

[00:08:27] So, I've had some examples in a code base where there's this div and it's got some click handlers on it. It's responding to clicks and keyboards, but it's not supposed to be interactive itself. It's trusting that there's a button downstream that kicks off an event and bubbles up the div, kinda catches it, does some extra stuff, and then just lets it go through again.

[00:08:50] Is that something we should generally try to avoid? Or is that something we're just, I guess, user beware when you're trying to do something like that? It's like ARIA where you can very easily mess things up, and you just have to be very careful with how you're setting things up and getting them wired.

[00:09:09]
>> Great question. So there are legitimate uses of click events on divs. So I'm glad you brought it up, because not everything needs to be wrapped with a button. So I guess that's a potential gotcha that I'm just so glad that you asked this question because we don't need to wrap a button around everything.

[00:09:28] Only interactive things. So say you've got a card component that the whole thing needs to be clickable, but you can call that same function off of a button on the card or from a link. You can do the same thing on an interactive element within the card. It is perfectly fine to put a JavaScript mouse event so that you can click the card, but then, there's still a reachable, operable target within it that you can get to from the keyboard.

[00:09:58] That is why it's a little bit hard for automated tooling to catch this type of issue. So we're gonna talk about that later too. Because it's fine to put a click event on something that's not reachable, as long as you can do the same function another way. So yeah, it can be done, and it's why Axe doesn't flag stuff like that.

[00:10:18] Cuz the computer can't always tell whether it's legit or not. [LAUGH] It's kind of subjective, it can be hard to tell. But you will know, and you can write some feature tests around that stuff that bake in a contract of like, this should be clickable, this part should be focusable.

[00:10:34] And I can write tests that assert all those things. And then that can help with clarifying how it should work. It'd be like, no, no, this click event is okay. These want like, that's because there's this other thing that does the same functionality.