If you follow many developers or web designers on Twitter, you may have seen the following tweet:

The attached photo is of the 2016 Fronteers Conference stage, with a projected slide that reads: “In 2016, it’s okay to build a website that doesn’t work without JavaScript”.

There’s a bit to unpack in that slide. And oh the unpacking people did. My Twitter timeline was a flurry of rants both for and against “JavaScript”, and many of those tweets came from people with no actual context of the talk’s intent. We’re collectively great at getting mad on the Internet, aren’t we? Good job everyone.

[Quick aside, Nolan Lawson, the person who gave the talk, posted a great follow-up article titled: Progressive enhancement isn’t dead, but it smells funny. I suggest you read it.]

Through the tweet storm, there was one particular topic that I was drawn to: whether or not a JavaScript reliant website or application was considered inaccessible if said JavaScript were unavailable.

I want to talk about this for a bit; but before I do, I want to level set a bit with the two following terms, “Accessibility” and “Universal Design”.

1. Accessibility

Accessibility means people have access to, the ability to use, and are not barred from the benefit of products, services or information because of special needs or disabilities. Note: accessibility does not mean that everyone has identical access. That’s not actually possible. However, it does mean that while access may not be identical – the end goal must be as equal as it possibly can be.

An accessible interface can be interacted with and its content can be consumed in a variety of ways. Whether that be via keyboard instead of a mouse, via screen readers and audio descriptions of what would otherwise be primarily visual content, or transcripts of audio and video. Regardless of the means, an accessible interface ensures that all users get the same information and can perform tasks that lead to the same outcome (e.g., mouse click or hitting Enter both activate links).

One of the most common physical examples of accessibility is stairs and ramps. They both allow entry to an elevated entryway, but each provide different pathways to get there.

2. Universal Design

Universal design can begin with an emphasis on creating accessible experiences, but its focus is not solely on users with disabilities. Instead, universal design promotes the idea that products, services and information should be usable to everyone, regardless of disability, age, or even technological constraints.

An interface that adheres to universal design principals should inherently be accessible, since the UX and technology decisions behind it are focused on comprehensive usability for everyone.

Now one of the most popular physical examples of universal design is a curb cut (ramp). This incline in the curb enables people in wheel chairs to cross roads without requiring assistance to get down or back onto a sidewalk. But it also makes crossing the road easier for people riding bicycles, pushing carriages or carts, and those using walkers.

With those two terms squared away, let’s get back to the question at hand…

Is an experience reliant on JavaScript inaccessible without JavaScript?

It is perfectly acceptable for an interface to require the use of JavaScript. [audible gasps go here] JavaScript is an integral piece in creating modern day websites and applications. Depending on what it is you’re building, it will even be required to ensure that an interface is accessible. By using JavaScript to close any usability gaps from custom UI components, or unsupported native HTML elements (i.e., <dialog>), we can provide expected keyboard functionality and semantic intent to assistive technologies (ATs).

But, in an age of single page web applications and relying on JavaScript to dynamically generate content, components, and even entire screens, what happens when JavaScript fails? Doesn’t that lead to inaccessible experiences?


A failure of everything

First let’s look at a situation where JavaScript is required. A website or application built in the popular JavaScript framework of the week, where all content is dynamically loaded into a single <div id="app"><div>. In this scenario, if JavaScript fails nothing loads at all. Surely being presented with nothing more than a blank white screen must be an inaccessible experience?

Until recently, I thought so. My reasoning being that while sighted users have a few visual cues as to what’s going on in these sorts of situations, users with visual impairments may not. A loading indicator in the browser’s address bar may still be spinning, indicating that something isn’t going quite right. Or the fact that sighted users can immediately see an empty, unstyled white page when they might otherwise know that the page they were attempting to access normally has a different background color, or, you know…content.

Visually impaired users may not get as much context. A screen reader might return a message like “HTML content is empty”, or “[Browser-name] is busy” but that doesn’t immediately explain what has happened or why. Is the page empty now, but I just need to wait for it to load? How long is this going to be busy for? What is the problem?

And that’s what my hang up was. It was the lack of immediately understandable context that had me thinking this was an accessibility issue. But, I was mistaken.

Since nothing was loaded there’s really nothing inaccessible about it. It’s a failed experience for everyone. And that visual context I was speaking of? That was my own bias/ignorance. Being a developer I know to look for these things — I can suspect failures and then test against those guesses. The average user is not a developer, and many don’t possess the context to pick apart what’s causing a website to fail, that I projected onto them. Returning a message saying “JavaScript is required”, when it’s been either blocked on purpose or due to a failure wouldn’t likely help most people. They’d shrug, maybe swear at their phone, and then just try to load another website.

In my opinion, just because this isn’t an issue of inaccessibility that doesn’t make it OK. A complete failure of loading any content is still a frustrating user experience, and can be considered a universal design issue. There are methodologies one might be able to implement to mitigate this sort of scenario. I suggest reading up on not-so-new topics like progressive enhancement and graceful degradation, off-line first, and service workers to see paths that could be applicable if you currently find yourself in an all-or-nothing situation with your own project.

I’d talk about them here, but that’s not what this post is about. Since we’ve identified that this scenario isn’t an accessibility failure, what would constitute as one?

Content loads, but without JavaScript it’s inaccessible

Where JavaScript failing becomes an accessibility issue is essentially when we don’t use it properly in conjunction with writing semantic markup and being mindful of our CSS.

Let’s take a look at the following example:

See the Pen JS-reliant Accessibility by Scott (@scottohara) on CodePen.

The menu toggle button still ‘works’ without JavaScript, but not without some accessibility issues due to the way it was constructed. The hard coding of the ARIA attributes in the markup means that, without JavaScript, screen readers will never expose anything but the hard coded state of the component.

The <a role="button" aria-expanded="false" ...> will announce the link as a button to screen readers. Without JavaScript the expected keyboard controls for either Space or Enter to trigger the button won’t work (links only accept Enter by default). More over, the aria-expanded="false" will convey that the element this toggle controls isn’t open (i.e., “expanded”), even if a user does actually use a mouse click or the Enter key to trigger the link, activating the :target pseudo selector that reveals the menu with CSS alone.

Finally, the hard coded aria-hidden="true" on the <ul> will ensure that even if a user does get the menu open and attempts to navigate to the exposed content, those links won’t be properly exposed.

As we can see from the situation above, the JavaScript failing wasn’t actually creating the accessibility issues. Rather, it was that the markup didn’t degrade gracefully. The hard-coded ARIA attributes needed JavaScript to allow the component to appropriately change state. Without the JavaScript, the attributes muddle the native semantics and discoverability of the content.

So, is JavaScript in the clear then?

As far as accessibility is concerned, there’s nothing wrong with requiring JavaScript for your website or application. When JavaScript fails, accessibility issues are more likely to exist due to underlying misuse of markup and styles.

As far as where JavaScript specifically affecting accessibility is concerned, it’s when one doesn’t follow appropriate recommendations in building custom UI elements, or when abusing JavaScript to do things like:

  • trapping user focus in an element
  • overwriting expected keyboard controls
  • moving focus or loading new pages without user initiation
  • etc.

but even then you can’t really blame it on the JavaScript, as it’s doing exactly what someone told it to do.

Steve Faulkner may have said it best: