Stop making clickable DIVs

Making the web accessible one (less) DIV at a time.

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>
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>

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.

Liked what you've read?
Follow me on LinkedIn!