Accessibility

But sometimes links look like buttons (and buttons look like links)

In Resilient Web Design Jeremy Keith discusses the idea of material honesty. He says that “one material should not be used as a substitute for another, otherwise the end result is deceptive”.

Making a link look like a button is materially dishonest. It tells users that links and buttons are the same when they’re not.

In Buttons In Design Systems Nathan Curtis says that we should distinguish links from buttons because “button behaviours bring a whole host of distinct considerations from your simple anchor tag”.

For example, we can open a link in a new tab, copy the address or bookmark it for later. All of which we can’t do with buttons.

Inclusive Tooltips & Toggletips

Most of the time, tooltips shouldn’t be needed if you provide clear textual labeling and familiar iconography. Most of the time toggletips are a complex way of providing information that could just be part of the document’s prose content. But I see each of these components all the time in auditing websites, so I wanted to provide some guidance on how to make the most of them.

Checklist

  • If you have space, don’t use tooltips or toggletips. Just provide clear labels and sufficient body text.
  • If it’s a tooltip you are looking to use, decide whether the tip’s content should be provided as the label or description and choose ARIA properties accordingly.
  • Don’t rely on title attributes. They are not keyboard accessible and are not supported in many screen reader setups.
  • Don’t describe toggletips with aria-describedby. It makes the subject button non-functional to screen reader users.
  • Don’t put interactive content such as close and confirm buttons or links in tooltips or toggletips. This is the job of more complex menu and dialog components.

Developer-facing implementation errors

This is a great way to guide other developers who may use your code or components to use the correct elements for accessibility and other reasons:

In our script, we can detect the element nodeName and return an error message if it is not BUTTON. We use return to stop the remainder of the IIFE (Immediately Invoked Function Expression) from executing.

Code language: JavaScript

if (toggletip.nodeName !== 'BUTTON') {  
  console.error('Toggletip buttons need to be <button> elements.')
  return;
}

CSS tests and error messages

In Inclusive Design Patterns I write about creating deliberate visual regressions to highlight code errors, and providing error messages in the developer tools CSS inspector.

The error we caught with JavaScript earlier can be caught using the CSS selector [data-tooltip]:not(button). We can highlight the erroneous element with a red outline, and provide an error message using the made-up ERROR property:

Code language: CSS

[data-tooltip]:not(button) {
  outline: red solid 0.5em;
  ERROR: Toggletip buttons need to be <button> elements.
}

Despite being an invalid property, the ERROR will appear in dev tools when the element is inspected.

Windows High Contrast Mode

Windows users are offered a number of high contrast themes at the operating system level — some light-on-dark like our inverted theme. In addition to supplying our theme switcher feature, it’s important to make sure WHCM is supported as well as possible. Here are some tips:

  • Do not use background images as content. Not only will this invert the images in our inverted dark theme, but they’ll be eliminated entirely in most Windows high contrast themes. Provide salient, non-decorative images in <img/> tags with descriptive alt text values
  • For inline SVG icons, use the currentColor value for fill and stroke. This way, the icon color will change along with the surrounding text color when the high contrast theme is activated.
  • If you need to detect WHCM to make special amendments, you can use the following media query:

Code language: CSS

@media (-ms-high-contrast: active) { 
  /* WHCM-specific code here */
}

Light/Dark Theme Switcher using CSS Invert Filter

Here’s a really straightforward dark theme switcher for light designs. It uses the CSS invert() filter and minimal JavaScript to switch it on and off.

Screenshots of The Boston Globe and The Independent with the CSS invert filter applied.
The Boston Globe and The Independent with the CSS invert filter applied.

Code language: CSS

:root { 
  background-color: #fefefe;
  filter: invert(100%);
}
 
* { 
  background-color: inherit;
}
 
img:not([src*=".svg"]), video {  
  filter: invert(100%);
}

Solutions for creating more accessible SVGs

We’ve been working with SVGs a lot recently, which has led our developers down a rabbithole of discovery! Here are some things to consider when it comes to SVGs and accessibility.

[…]

1. <img> tags and SVGs

When SVGs are implemented as <img> tags with an .svg as the source, we’ve encountered a few issues for VoiceOver and TalkBack users. These issues occur when those <img> tags don’t also have an ARIA role=”img” attribute.

[…]

2. <title> tags and SVGs

We often see examples of making SVGs accessible by simply adding a <title> element within the inline <svg>. While this does help in some situations, like a lone SVG icon within a link, adding a <title> element doesn’t make SVGs accessible in all browsing environments.

[…]

For example, when using Firefox and NVDA, a link containing an SVG would be recognized as a link, but the text within the <title> element would not be announced. NVDA announces the path within the href attribute only.

Adding an aria-labelledby attribute to the SVG can help expose the text within the <title> element to the browser’s accessibility API. However, even with this in place, NVDA does not announce the <title> text as we might expect.

Our most recommended approach when it comes to browser support and consistency across screen readers is to add a visually-hidden element as a sibling element to the <svg>. With this implementation, we’ve found that all browser and screen reader combinations tested were able to announce the link with the expected text announcement.

We also recommend adding aria-hidden=”true” to the <svg> element itself. This is to help prevent having any other text that may be embedded within the SVG be announced by screen readers. Then, the only text that should be announced would be the content within that visually-hidden element.

[…]

7. Colour contrast

While not a bug per se, we also see a lot of cases where designers and developers don’t plan for colour contrast issues for SVGs. Since SVGs function just like transparent GIFs in how they are displayed, different page background colors and effects can cause unanticipated issues for low vision users.

For example, a black SVG icon that’s perfectly visible with a white page background is going to be invisible in a Windows High Contrast theme that uses a black background. This is a common use case for users who use High Contrast settings due to light sensitivity or related issues. When you provide a solid background or contrasting border for SVGs, you can help avoid those kinds of problems.

Responsive Design for Motion, a.k.a. "prefers-reduced-motion" Media Query

WebKit now supports the prefers-reduced-motion media feature, part of CSS Media Queries Level 5, User Preferences. The feature can be used in a CSS @media block or through the window.matchMedia() interface in JavaScript. Web designers and developers can use this feature to serve alternate animations that avoid motion sickness triggers experienced by some site visitors.

To explain who this media feature is for, and how it’s intended to work, we’ll cover some background. Skip directly to the code samples or prefers-reduced-motion demo if you wish.

Inclusive Toggle Buttons

How you design and implement your toggle buttons is quite up to you, but I hope you’ll remember this post when it comes to adding this particular component to your pattern library. There’s no reason why toggle buttons — or any interface component for that matter — should marginalize the number of people they often do.

You can take the basics explored here and add all sorts of design nuances, including animation. It’s just important to lay a solid foundation first.

Checklist

  • Use form elements such as checkboxes for on/off toggles if you are certain the user won’t believe they are for submitting data.
  • Use <button> elements, not links, with aria-pressed or role="switch" plus aria-checked.
  • Don’t change label and state together.
  • When using visual “on” and “off” text labels (or similar) you can override these with a unique label via aria-labelledby.
  • Be careful to make sure the contrast level between the button’s text and background color meets WCAG 2.0 requirements.

See the source link for very detailed descriptions of all of these points.

Introducing A11y Dialog

Almost all projects involve some form of dialog window at one point or another. However, accessibility is all too often set aside in favor of quick implementation. Truth is, accessible dialog windows are hard. Very hard.

Fortunately, there is a super clever guy named Greg Kraus who implemented an accessible modal dialog a few years ago and open-sourced it on GitHub. Now that’s nice!

However, his version—no matter how good it is—requires jQuery. We try to avoid using jQuery as much as we can here. We realised we did not really need it most of the time. On top of that, his script is not very flexible: only one dialog window per page, hard-coded IDs inside the functions. Not very practical and certainly not a drop-in script for any project.

So I rolled up my sleeves and improved it.