Easier paths to accessibility in Elm
Tags: elm, a11y
Published: 2019-10-11 16:19:45

---
title: Easier paths to accessibility in Elm
published: true
description: 
tags: elm, accessibility, a11y
---

Accessibility is a big topic. It covers all sorts of things that affect people in different ways, but it's also something we can improve with some minor changes. For example, take the following element:   

![A select input](https://thepracticaldev.s3.amazonaws.com/i/ifwcj8y4olif9895iyxm.png)

Looks fine, right? 

Well...not quite. This _looks_ like a normal select input, but it's really a div and a span, both with an onClick handler, as well as a span that has the same onClick handler. 

The problem is that neither `div`s nor `span`s should have onClick functionality.   

When someone types in this field the application suggests booking statuses as they're typing. These appear in a drop-down that looks like a select:   

![A dropdown showing suggested results](https://thepracticaldev.s3.amazonaws.com/i/4vuqriyx8cc1ecb7n44v.png)

The user is presented with more divs containing suggestions, each with onClick handlers. What happens when you select one of them?   

![The original select input, now with an item inside](https://thepracticaldev.s3.amazonaws.com/i/6rirpassgmk0nbb3ltys.png)

Now we have extra buttons: one for deleting the selected item, and one for deleting _all_ the selected items. Would it surprise you to learn that these aren't buttons either? Spoiler alert: both are also spans. 

What if all of the things that are pretending to be buttons right now really were buttons?   

![An input field](https://thepracticaldev.s3.amazonaws.com/i/wsd2zx7tobevc0stxlt7.png)

This basically looks the same, but it isn't. We've changed the placeholder text to reflect what was previously hidden functionality. The arrow is now a button, which can be understood by screen-readers. Awesome.   

I can hear you now: _"But I don't use a screen-reader"_. I'm happy for you and your sightedness. But did you know that making this a button instead of a span gives us keyboard controls _for free_? 

I won't bore you with screenshots of the rest of the states this element can be in, but we've changed all of them to use buttons in the same way. Now every suggestion can be navigated through solely through the keyboard. The remove buttons can be selected in the same way. And it all looks exactly as it did before. 

## But you can use ARIA to solve this, right?   

Yes, you can. But, your application will happily let you forget. 

ARIA will help screen-readers understand that your elements are acting as buttons etc., but we should use HTML the way in which it was intended here. This is inherently understood by screen-readers as it has accessibility built-in by default.
  
That said, surely there's a way we can make this easier for people. Surely we can work towards accessibility being easier to implement. Surely we can make our applications accessible to the widest possible audience? 

## Enter: Elm's accessible-html module

Tessa Kelly is an engineer at NoRedInk. She has created an Elm module called "accessible-html" to solve this problem.  

This module ensures that people can't accidentally write HTML that falls foul of accessibility rules. It achieves this by failing to compile if you accidentally do so, for example:    

![An error from Elm's compiler, explaining that the first argument needs to be a list of "Attribute Never" rather than "Attribute msg"](https://thepracticaldev.s3.amazonaws.com/i/dtgx0zk28le4ni995n4o.png)

Here I've tried to call a div with an "onClick", but Elm's compiler has rightly pointed out that this is not possible.

Here's another example:   

![An error from Elm's compiler, explaining that an argument needs to be a String rather than a list of "Attribute msg"](https://thepracticaldev.s3.amazonaws.com/i/eb73161yp8th2fp2fvk6.png)

The compiler is telling me that the "img" function needs a String as its first argument. This is because `accessible-html` won't allow you to have an image without alternate text. This means that the image will always be described if it doesn't load for any reason, including for people using screen-readers. 

Here, our own tooling _makes us better engineers_ by _actively teaching us_ the rules of accessibility.

Since this module extends the core `HTML` module, it is _almost_ a drop-in replacement. The only things that need attention are where accessible-html's API differs from HTML's, as it does with the "img" function we've already looked at.

As I mentioned at the start of this post, accessibility is a big topic. We need to ensure we're considering it at design _and_ implementation stages. Tools like this make it a lot easier.

### Things mentioned in this post: 

[accessible-html](https://package.elm-lang.org/packages/tesk9/accessible-html/latest/)

[Tessa Kelly (Twitter)](https://twitter.com/t_kelly9)

[ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA)