Accessibility in the Age of the Headless CMS


A few months ago I asked in the Human Made general Slack channel: “What shall I talk about at WordCamp Europe?”
And the honourable Ant Miller replied: “Accessibility in the age of the headless CMS.”

React logoGreat, I thought. A new subject, much to learn and tell about, I started to read up on the subject. And then I realised: oh no, I have to learn React!

I’m way out of my comfort zone here.

Learning React in a few months, next to my other work was kind of too ambitious. Thankfully I have some great colleagues who know a lot about this subject. So much possibilities: one page (app like) sites, fast and dynamic, integration with the REST API. Fun to learn!

And while learning, I realised what my talk should be about: how to handle dynamic changes with assistive technology.
But first of all I want to talk about what struck me the most: the loss of true coding craftsmanship.

So: I will start with how to safeguard the quality of your code in the frontend, after that how to handle dynamic changes in the content for screen readers and will finish with some ideas about performance and usability.

1 The DOM

Code is poetry

If you take yourself seriously as a developer you ask someone to review your code. The PHP code must comply with WordPress Code standards, you know: escape all the things, give the code air to breath by adding spaces, Yoda conditions, document the code. The JavaScript must be without errors.

Maybe you also have to check for VIP code standards to check for performance. You have to get creative and go through great lengths if you are not allowed to use get_terms().

If we take so much effort in getting good quality code: Then why don’t we validate what ends up in the DOM (the Document Object Model)?
It seems like a forgotten craft, writing true semantically correct meaningful HTML5.

This is not the fault of React, this totally due to the ignorance or lack of knowledge of the coder. So, what to do?

Use semantic, meaningful HTML5

Yes, I told this before, in previous talks. But while learning React it struck me that using HTML5 wrong is getting worse and worse.

These are code examples in online courses and code I found in the wild.

Don't copy this, this is wrong code. Don't add inline CSS and don't add an onClick to a list element. 
    style={lang === props.selectedLanguage ? {color: '#d0021b'} : null}
    onClick={props.onSelect.bind(null, lang)}
Don't copy this, this is wrong code. Don't add inline CSS and don't add an onClick to a div element and don't use all divs in your HTML5. 
render: function() {
        return (
                    style = {{
                        background: this.state.color,
                        width: 100,
                        height: 100
                    onClick = {this.changeColor}

For crying out loud: div and span don’t get keyboard focus!

Having the a click action on an <li> element only works for mouse or touch interaction. And not for keyboard users, but also all the other devices that interact with your site, like for example voice control.

Inline CSS is something we did in the 90’s, before the invention of the stylesheet. Separate your CSS from the HTML, use classes. It’s so easy to stay in your JavaScript bubble, but take pride in the quality of the code that ends up in the DOM.

  • use the <a> element for a change of location (this also can be an internal link, like #about)
  • use the <button> element to invoke an action

Then you get all behaviour for free!

Google the words “React div onClick” and be amazed how creative people can get ignoring the obvious: use a button …

All DIVs create a meaningless DOM

React coders seem addicted to the <div> element. This creates a flat meaningless DOM.

<sarcasm>Just put everything in a <div>, add the CSS styles inline and you’re done. Why? Because you can get away with it. And it works for you. Why use separate CSS if you just can stay safely in your JSX bubble.</sarcasm>

What happened to “user first”? Get out of your JavaScript bubble! Don’t JavaScript all the things! Please don’t use inline style because you can’t be bothered writing an extra class.

Personally I don’t get this.
React is difficult to learn. Especially if you dig deep into it. It is hard work.
Then why don’t you pay any attention to the quality of what ends up in the DOM? Because the DOM is what the user interact with. Use meaningful HTML5.

Code is poetry.
Take pride in your workmanship.

HTML5, that’s what served to all the technology that reads your page.
Not only your desktop, laptop, tablet, smartphone, iWatch. In the future maybe also your refrigerator, car or whatever ways we invent to interact with the interwebs. This is not only important for accessibility, but also for sustainability. Build for the future.

HTML5 logoSo: Learn HTML5 deeply.

It’s not rocket science. If you can master React, learning HTML5 is easy. A very good resource is Maintained by people who also write the HTML5 specs. With documentation on all HTML5 elements and posts about recent developments.

Accessibility is not holding back the speed of development of WordPress, it safeguarding the code quality and sustainability. We go far to make our PHP, JavaScript and performance perfect, please take as much care of what ends up in the DOM.

Validate the DOM

There are a few ways to validate the DOM:

  1. Keyboard test
  2. Run your page though the HTML validator of 3WC
  3. Run your page though the CSS validator of W3C
  4. Use test software like aXe, by Deque Systems

I particularly like aXe. I use the browser extension that adds a tab to your inspector with an option to analyse the page for HTML and accessibility errors.

axe tab in the inspector

But you also can use aXe-core as NPM module and integrate it in your Gulp or Grunt routine.

Dynamic changes

So: here the fun starts.

Dynamics is what makes React and integrating the REST API valuable and so much fun. No page reload, all the data is already there, super fast and flexible.

If your eyes work you can see the changes. But what if you can’t see that well? Then the changes need to be announced to you, so you can hear them. Or feel them, if you use a braille line.

How to do this? Here ARIA comes to the aid. WAI-ARIA means “Web Accessibility Initiative – Accessible Rich Internet Applications“, also known as ARIA.

ARIA are attributes you can add to HTML5 elements to give assistive technology information on what’s going on. ARIA is supported in the latest versions of all major browsers and assistive technologies support ARIA. Increasingly, JavaScript widget libraries such as jQuery UI include ARIA markup as well.

First rule of ARIA: don’t use ARIA!

This seems contradictive, but ARIA is not to fix bad or over complex HTML5.

Rule of thumb: If there is a pure HTML5/CSS solution: use that! You get all functionality for free. Keep it simple.

When is ARIA useful?

It’s all about giving the user of the device feedback:
What happens on the page, what does it mean, how can I interact?

I want to give you an example of 2 uses of ARIA for dynamic pages


<div aria-live=“polite”>

    <p>This is where the magic happens</p>


What changes inside an element with aria-live will be announced by a screen reader.

Aria-live has two different behaviours:

  • aria-live=“polite” : updates announced if the user is idle
  • aria-live=“assertive” : updates announced as soon as possible


Is a menu open or closed? You can add this information to the button that toggles (show/hide) the content with jQuery (for example).

<button aria-expanded="false" class="expandable">Great quote</button>

<div aria-hidden="true" class="expanded-content">
        <p>Make our planet great again</p>
             — <cite>Emmanuel Macron</cite>

The aria-expanded is put on the button, because that’s what gets focus and is announced. The user can decide to open the content and read from there, or don’t open it and then the content stays hidden.

Good resources for ARIA:

3 Progressive enhancement

There is much to say about this, and also much to research!

To say it simple:
Progressive enhancement means:

  • serve content first (HTML)
  • then add the presentation (CSS)
  • and after that add the client side scripting (JS)

first content, then presentation, then client-side scripting

But what decisions to make, when the content is heavily depending on the scripting, as it is with a one page site?

What I would like to propose for now:

  • build the HTML5 framework first
  • have all CSS in a separate css file and never inline
  • determine what is dynamic and script for that only
  • serve initial content

This will ensure the user will get meaningful content served before the JavaScript kicks in.

Last take away from my research

Niet omdat het moet
maar omdat het kan

This is a Dutch saying meaning:
“Not because you must, but because you can”.

If you are a clever, hardworking coder, spending much time learning, studying how to build complex applications. Please take a step back and look at your work, and ask yourself: Am I serving my user or my ego?

The W3C HTML Design Principles state:

over authors
over implementors
over specifiers
over theoretical purity

Or, to speak with Jeff Goldblum in Jurassic Park:

Jeff Goldblum in Jurassic Park

Developers are so preoccupied with whether or not they could,
that they didn’t stop to think if they should.

Don’t create a monster.

Code is poetry
Write a poem with your HTML5