DEV Community

Suhan Wijaya
Suhan Wijaya

Posted on • Originally published at tech.boxed.com on

Accessible UI: Stop making clickable DIVs

Source: Make a Meme

I used to think that accessibility is at best a UX improvement, and at worst “compliance work”. But as the pandemic turned Boxed.com into an essential service for many of our customers, I have read a good number of heartbreaking customer service tickets that revealed my biases and the unintended exclusions caused by my code. Now, I’m convinced that making the web accessible is the right thing to do.

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

Source: CoderPedia

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>
Enter fullscreen mode Exit fullscreen mode

What’s your approach to creating clickable UI components? Let me know in the comments.

Note: I decided not to discuss aria attributes because I think they deserve their own article.

📫 Hit me up on LinkedIn or Twitter!

Top comments (0)