Stop making clickable DIVs
Accessibility is a broad topic, and a subset of loftier inclusive design principles that I won’t pretend to be an expert on. I’m just sharing one of the many a11y lessons I learned as a developer.
So let’s move on to the main topic.
We love our div
tags. But, simply from a developer experience standpoint without even discussing the merits of semantic HTML (which deserves its own article), a button
is more accessible with less code compared to a clickable div
. To illustrate, let’s go ahead and create a clickable div.
<div>Click me</div>
<script>
function doSomething() {
console.log("do something");
}
document.querySelector("div").onclick = doSomething;
</script>
Not good enough, we need to visually indicate through the cursor type that the div is clickable (which apparently is also debatable). Let’s add some CSS.
<style>
.someDiv {
cursor: pointer;
}
</style>
<div class="someDiv">Click me</div>
Not good enough, we need to verbally indicate through screen readers that the div
is a clickable button, and it needs to be keyboard accessible via Tabbing navigation. Let’s add role and tabindex attributes.
<div class="someDiv" tabindex="0" role="button">Click me</div>
Not good enough, the div
also needs to be keyboard accessible via Enter and Space Bar keys. Let’s add more JavaScript (which may not even be 100% cross-browser compatible).
<script>
function doSomething() {
console.log("do something");
}
function handleKeydown(e) {
if (e.key === "Enter" || e.key === " ") {
doSomething();
}
}
document.querySelector("div").onclick = doSomething;
document.querySelector("div").onkeydown = handleKeydown;
</script>
So finally, we end up with this.
<style>
.someDiv {
cursor: pointer;
}
</style>
<div class="someDiv" tabindex="0" role="button">Click me</div>
<script>
function doSomething() {
console.log('do something');
}
handleKeydown(e) {
if (e.key === 'Enter' || e.key === 'Space Bar') {
doSomething();
}
}
document.querySelector('div').onclick = doSomething;
document.querySelector('div').onkeydown = handleKeydown;
</script>
Whereas, the button
version that’s equally accessible looks like this.
<button>Click here</button>
<script>
function doSomething() {
console.log("do something");
}
document.querySelector("button").onclick = doSomething;
</script>
What’s your approach to creating clickable UI components?
Note: I decided not to discuss aria attributes because I think they deserve their own article.