Skip to content

reloadedhead/accessible-labels

Repository files navigation

Accessible labels and where to find them

Introduction

What means an accessible web?

The Web is fundamentally designed to work for all people, whatever their hardware, software, language, location, or ability. When the Web meets this goal, it is accessible to people with a diverse range of hearing, movement, sight, and cognitive ability.

❕ Web accessibility, in all its means, can be an extensive topic that would require more than a 15 minute talk. Therefore, from now on until the end of this document, I will focus on vision assistance through screen readers.

Accessibility is essential for developers and organizations that want to create high-quality websites and web tools, and not exclude people from using their products and services. One can not only encompass those who directly require assistance, but also people without disabilities.

Status quo

Who is DRI here?

Even though we are all responsible on making the web accessible to everyone, the Web Accessibility Initiative provides an international forum for collaboration between industry, disability organisations, accessibility researchers, government, and others interested in web accessibility. Anyone can contribute and there are several Community Groups that are actively looking for contributors.

How can software assist?

Screen readers are software programs that allow blind or visually impaired users to read the text that is displayed on the computer screen with a speech synthesizer or braille display. A screen reader is the interface between the computer's operating system, its applications, and the user.

Usual suspects for system-wide accessibility include:

  • Eye-Pal
  • iMax for Mac
  • JAWS
  • Voice Over

When it comes to browsers, mayor vendors come with screen readers built-in. If we are talking about Safari, you get VoiceOver for free from the OS (macOS, iOS).

Google Chrome does offer Screen Reader, a browser extension, but they recommend using a fully fledged software such as ChromeVox (ChromeOS only), VoiceOver on the Mac and JAWS, NVDA or Narrator in Windows.

Microsoft Edge comes with a built-in screen reader, available in both Windows and macOS.

As of the time of writing, both Google Chrome and Microsoft Edge ship with a screen reader.

Firefox on the other hand, does not ship with a screen reader by default. However, it provides basic support for VoiceOver on Apple platforms and does link to several add-ons users can install on any platform.

Some interesting stats

I came across the screen reader survey #8 by Web AIM (Accessibility in mind), which provides a nice overview on some topics from a screen reader user perspective. It's worth a read, and you can even compare how these results have evolved over time. What I believe it's important to take from these results, is the reasons the interviewees believe accessibility in the web is lagging behind. Lack of awareness is the most voted reason, which is something that we can fix overtime. It's important to note how critical can be having a good level of accessibility for a human being, either if it's for work or for browsing Reddit at 3:00 in the morning.

Reason Percentage
Lack of awareness 38 %
Lack of skills 34%
Fear of hindering the feature 18%
Lack of budger 9%

Are screen readers a silver bullet?

Any piece of software is made by humans. Therefore, no software is bullet proof. One can navigate through WebKit’s BugZilla, filtering by VoiceOver or going to Chromium’s site and doing the same.

WebKit’s list of screen reader related issues.

WebKit’s list of screen reader related issues.

Chromium’s  list of screen reader related issues.

Chromium’s list of screen reader related issues.

I encourage you, if you unfortunately find any bug (within any topic, not just screen readers!), do report it! Help the maintainers of these open source projects to improve their product by reporting unexpected errors and how to reproduce them.

Use case: measurements

The problem

At some point in your career as a web engineer, you probably displayed some kind of number with a context behind it. After all, it would be quite weird to show the number 42 without any explication. What is 42?

We can be speaking about 10 double quarter pounders, 75% annual inflation or 1 banana. Instead of keep throwing numbers and their units of measurements, I raise you a more common, day to day example: € 6,50. If you are reading this, your mind probably parsed that as six euros and fifty cents. By the way, that’s what my favourite chicken kebab costs 🌯. That is pretty easy, right? You might wonder how screen readers perform? Well, pretty neat! Voice over will read that just like your brain. That’s awesome!

However, not everything in life is nicely-priced kebabs. Imagine you are using a web application to measure your CO₂ emissions. Something that has been gaining track as of late. How would you read the following 1.500,78 Kg CO₂ (aside: that’s how you measure, generally, CO₂ emissions). You probably went one thousand five hundred and seventy-eight kilograms of carbon dioxide. A quick run in VoiceOver, throws one thousand five hundred seventy-eight key ge ce o two.

That’s not a rap verse, VoiceOver, that's a valid unit of measurement!

Thinking of a solution

Wouldn’t it be nice to have a library to build user interfaces via reusable components? Oh wait, we have React. Side-note: you can achieve the very same result with other libraries or frameworks. I will just use React. We already know where are we standing, that mouthful of speech, and we know where we want to go. So let’s start.

Simple as HTML

Beginning with the obvious, a simple span tag to render a number.

<span>1500.50 Kg CO₂</span>

We can improve this situation by adding some context. Units of measurement are, generally speaking, abbreviations. Luckily, there is an HTML tag for that! The abbr tag represents an abbreviation or acronym, and can provide an expansion via the title attribute.

<div>
  <span>1500.50</span>
  <abbr title="Kilograms of carbon dioxide">Kg CO₂</abbr>
</div>

And voliá! We have reached to our destination. That’s all folks. Right?

Let’s add some React to it

What if you want to reuse this little thing we have just built? What if you have multiple units of measurements? We need to enhance this. We can, and we will.

Firstly, we can create a React component out of our little markup.

const Amount = () => (
  <div>
    <span>1500.50</span>
    <abbr title="Kilograms of carbon dioxide">Kg CO₂</abbr>
  </div>
);

We can also start talking some API decisions. For now, let’s make Amount a functional component, and represent the numerical amount the sole child.

const Amount: FC = ({ children }) => (
  <div>
    <span>{children}</span>
    <abbr title="Kilograms of carbon dioxide">Kg CO₂</abbr>
  </div>
);

/** Usage */

const App = () => (
  <div>
    <Amount>
      1500.5
    </Amount>
  </div>
);

Now, lets focus on the unit of measurement. It would be nice to just tell the Amount component that we want to render a KgCO₂ amount in this particular case. Here is when you will have to start thinking on your own context.

In addition, our component will require some sort of unit object, that will store our symbol (Kg CO₂) and the corresponding definition. We can think this object like so:

type Unit = {
  /** Symbol of the unit of measurement, e.g. CO₂. */
  symbol: string;
  /**
   * Definition of the unit of measurement.
   * Can be a function that takes the amount and defines accordingly
   **/
  definition: string | ((value: number) => string);
  /**
   * Optional function that will format the amount.
   */
  formatter?: (value: number) => string;
};

Bonus track: include an optional formatter function that will take care the number formatting!

Our Amount component will look like this:

type Props = {
  /** Unit to define this amount. */
  unit: Unit;
};

/**
 * A simple component that will make units of measurement more accessible.
 */
export default function Amount({ children, unit }: PropsWithChildren<Props>) {
  const title =
    typeof unit.definition === "function"
      ? unit.definition(Number(children))
      : unit.definition;

  const amount = unit.formatter ? unit.formatter(Number(children)) : children;

  return (
    <div>
      <span>{amount}</span>{" "}
      <abbr className="no-underline" title={title}>
        {unit.symbol}
      </abbr>
    </div>
  );
}

💡 It is worth noting that the generation of this Unit is completely implementation agnostic. You can use your favourite i18n library, Intl’s built in databases and so on.

References

About

Little demo and talk about accessibility and units of measurements.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published