A11y: escaping the hell of good intentions

Accessibility (a11y) could be more subtle than you think.

You may have the best intentions, but if your implementation is poor, then your website won’t be usable for many users.

The hell of styling

It’s not uncommon to find crazy CSS rules that remove outline or associate colors with specific actions or messages, which excludes de facto many users.

In contrast, websites rarely care about focus styles, and if you remove outline, you also remove the default styles.

The hell of ARIA

ARIA roles can be difficult to understand.

It’s easy to add them everywhere, but it’s not the most clever strategy and the benefits for users depends on what information you provide.

For example, you may add some aria-label on nav, but if you use words like “navigation” or “menu”, screen-readers won’t give the best experience to users.

These devices already indicate that it’s a nav thanks to the landmarks.

If you don’t use the aria-hidden attribute to hide unnecessary elements from assistive technology, your website can be very noisy.

However, this attribute is only meant for non-interactive content like pure decorative images or svgs, repeated text, or offscreen content.

If you apply this to focusable elements, it’s a bad practice and an anti-pattern.

Some even say “Don’t use ARIA Menu Roles for Site Nav”.

The hell of incomplete implementations

Many websites don’t take into account keyboard navigation while they should.

However, even if you care, you might miss some interactions. For example, does the collapsed menu work without the mouse?

Many users expect to open the menu simply by pressing ENTER after selecting the toggle and close it with ESC.

I rarely see such implementation while it’s not particularly difficult to achieve, using some JavaScript, for example.

The problem is that if you start implementing some “features,” the level of expectations can raise dramatically, and you might miss other helpful components.

The hell of validators

Whether you use the HTML5 validator or Google’s online checking tools, you might get great indicators but, unfortunately, “false positives” too. The automated tests can even suggest adding some roles and other attributes while it does not make sense.

As a developer with good intentions, you will likely try to fix these warnings, but it’s not necessarily the best move, and you might even downgrade the user experience.

Of course, it does not mean you should not fix HTML errors, but special attributes affect the assistive technology and the accessibility tree.

The hell of a11y overlays

As a11y overlays come at the end of the line, it’s often too late to fix critical mistakes (e.g., in design). It might even give a false impression of compliance, and in the worst-case scenario, it conflicts with assistive technology, adding features already provided by screen readers or overriding native shortcuts, which forces users to learn additional techniques.

Everybody has an opinion

You can read posts that explain some techniques are useless and generate redundant markup, but others might beg to differ, as some implementations won’t be understood by old assistive technology.

Not all users can afford the latest fancy devices, and there’s always a learning curve.

So a11y is hard, what do we do?

In my experience, a11y is full of traps and unexpected conflicts, so “less is more.”

Here are better solutions, IMHO:

  • test your website with real assistive technology (not emulators)
  • a11y by design is better than a11y by policy, just like privacy or security, so include it at the earliest stages of the project and not as an overlay
  • update your knowledge regularly and drop bad habits
  • use ARIA markup sparingly, for example, aria-label are meant for edge cases, so it’s not a generic rule for buttons
  • landmarks are critical but markup tags can not be used interchangeably, so not everything is a menu or a navigation
  • learn expected interactions (e.g., keyboard, mouse) by users (not only people with disabilities) and implement them carefully
  • don’t remove default focus styling or replace it with tested styles

For the last point, I often see the following styles:

*:focus {
  outline: none;

In the best-case scenario, additional rules replace the default focus styles, but I would prefer not to do that at all.

Feel free to disagree with me, but after testing various approaches that override the default styles, I think it creates more problems than it solve.