Skip to content

Instantly share code, notes, and snippets.

Last active July 8, 2019 10:26
What would you like to do?

Accessibility in Web

by Jacek Tomaszewski

Asana task


What is accessibility?

Accessibility is the design of products, devices, services, or environments for people with disabilities.

The concept of accessible design and practice of accessible development ensures both "direct access" (i.e. unassisted) and "indirect access" meaning compatibility with a person's assistive technology (for example, computer screen readers).

Accessibility can be viewed as the "ability to access". (...) The concept focuses on enabling access for people with disabilities, or special needs, or enabling access through the use of assistive technology. (...)

Accessibility is not to be confused with usability, which is (...) effectiveness, efficiency and satisfaction in a specified context of use.

Accessibility is strongly related to universal design which is the process of creating products that are usable by people with the widest possible range of abilities, operating within the widest possible range of situations. This is about making things accessible to all people (whether they have a disability or not). - Wikipedia

Why accessibility matters?

  • Morally good: nobody should be excluded from using your website.

  • Economically good: larger user base means greater product's profit.

  • Required by law: public institutions (and their services, websites) are required to be accessible by everyone.

    P.S. In some countries, this law might apply to private sector services as well.

  • Good PR: being helpful and accessible to all the users will drive good opinions and marketing to your product.

  • Better UX: Accessible design improves UX in general for all the users.

  • Better SEO: Accessible design encourages good semantics, which in turn makes your website look better in the eyes of a search engine.

Related: The Business Case for Digital Accessibility

Accessible web

What is accessible Web?

Wikipedia says accessible Web addresses following needs:

  • Visual: Visual impairments including blindness, various common types of low vision and poor eyesight, various types of color blindness;

  • Motor/mobility: e.g. difficulty or inability to use the hands, including tremors, muscle slowness, loss of fine muscle control, etc., due to conditions such as Parkinson's disease, muscular dystrophy, cerebral palsy, stroke;

  • Auditory: Deafness or hearing impairments, including individuals who are hard of hearing;

  • Seizures: Photo epileptic seizures caused by visual strobe or flashing effects.

  • Cognitive and intellectual: Developmental disabilities, learning difficulties (dyslexia, dyscalculia, etc.), and cognitive disabilities of various origins, affecting memory, attention, developmental "maturity", problem-solving and logic skills, etc.

In practice for web developers it will be:

  • Visual:

    • blindness (can't see at all),
    • low vision / poor eyesight (can't see small texts, can't distinguish similar colors),
    • color blindness (can't distinguish colors);
  • Motor/mobility:

    • inability to click moving objects
    • inability to click at all
  • Auditory:

    • can't or have problems to hear
  • Seizures:

    • feels bad when things are moving
    • feels bad when things are flashing
  • Cognitive and intellectual:

    • reading problems
    • has problems to write correct text
    • has problems to go through difficult, non-obvious UI
    • has short memory

Assistive technology tools examples

Some users use special tools in order to read/navigate through the Web:

  • Speech recognition - converts spoken word to text which served as input to the computer.
  • Screen reader - reads out the text that is displayed on the screen.
  • Screen magnification - enlarges the monitor and makes reading easy for vision-impaired users.
  • Special keyboard - makes typing easier for users with motor control difficulties.

Writing accessible web

For blind people

HTML semantics

Make sure that meaning of your content and interactive elements is covered by HTML tag names and attributes.

  • Look up HTML structure with:

  • Add meaning to elements by using proper tagName (h1-h6, article, section) or role (role="heading", role="article", role="section").

    • P.S. tagName is just a shortcut for setting role.

      For example: <div role="article"> === <article>.

  • Add aria- attributes that provide useful information to screen readers.

  • Hide elements from screen readers with aria-hidden, if they are visually hidden, but still present in the DOM.

  • Associate every form control with a label (using <label for="..."> and <input id="..."> or <div role="..." aria-labelledby="...">).

Text Content

Make sure all your content can be read by screen readers in a meaningful way to the blind user.


  • Provide alternate text to every image with alt attribute


    • if the image has no meaning from content perspective, that is it exists only for presentational purposes (i.e. bg.png), add role="presentational" to it

    • if the image would duplicate the text that is located next to it (i.e. card title and card image), still add alt attribute to it (for SEO purposes), but also add role="presentational" to it, so screen readers won't read it


  • provide alternate text for icons that are important for screen readers to be read
    • i.e. if a button has no text inside of it but only an icon, then provide aria-label to it (or put text that is hidden with CSS)

Links and buttons:

  • if a link or a button consists of vague text like "Apply" "OK" "View more", and thus it might not be obvious for users using screen readers to guess what the link/button does, add more explicit label to it with aria-label that gives more context about the link/button action ("Apply to job" "Confirm update" "View more about X").

Elements order:

  • try to mimic reading order in the DOM order

Keyboard focus

  • Always show where your :focus is

    • highlight the element if it is currently focused

      Note: elements like <button> or <a> are highlighted with outline: ... by default in all of the web browsers. (You can replace the highlight style if you want.)

    • To distinguish between mouse focus and keyboard focus (i.e. in order not to show the focus outline on mouse clicks):

  • Make sure everything is keyboard-navigatable

    • Every interactive element should be possible to be reached with TAB key

    • Everything that can be clicked with mouse should be also possible to be clicked with keyboard

      • use <button onClick> instead of <span onClick> (browsers will trigger onClick for the button element even if it has been clicked with keyboard)

      • or, whenever you add onClick, also add onKeyDown (and listen to ENTER/Space keys)


            onDescriptionClick &&
            (e => ['Enter'].includes(e.key) && onDescriptionClick())
      • Important note: Make sure that every modal/dropdown can be closed with keyboard.

        For example, if clicking with a mouse on backdrop is the only mouse-solution to close the modal, then at least include a hidden-but-keyboard-focusable button in the beginning/end of the modal.

    • Make sure you can't focus hidden elements.

      • Add disabled or tabIndex="-1" to elements that shouldn't be possible to be focused.
    • When opening/closing a nested view (i.e. dropdown, modal):

      • make sure user gets focused on it automatically once it is open
      • make sure user can't focus out of it by mouse click or TAB (or make sure that view is closed once he focuses out of it)
    • When focusing on an element, it should be visible in the viewport.

      • By default, browser scrolls down to it automatically once it is .focus()ed, but if you do some kind of CSS transforms, you might need to remember about it.

Async (dynamic) updates

If some content is changed/appended asynchronously (i.e. form success, form alert), screen readers should be informed about it thanks to aria-atomic, aria-live attributes.

More info: .

For people with poor eyesight


  • Validate contrast ratio of foreground and background colors ( that it passes WCAG AAA test.

    • ideally, test it automatically (and raise any color issues to designers after an error is found),
    • you can look it up also in Chrome Devtools.
  • Don't use color alone to convey information.

For people with seizures

Reduced Motion Media Query

  • Avoid big flashing elements (elements that suddenly and/or continously change colors/brightness).
  • Always let the user stop the flashing animation.
  • Try not to autoplay the animation on page init.

General rules

Always use native elements when possible

<input type="checkbox" checked />

is way better and easier to do than

<div role="checkbox" aria-checked onClick={...} onKeyDown={...} />

Only add aria- tags when they are needed and native attributes can't do the job

Mimic default browser behaviour as much as possible

For example, when doing your custom Select input with dropdown, take native select as an example for behaviour (i.e. keyboard/mouse behaviour), and refer to W3C docs for information about desired behaviour of aria- attributes.

Never use a11y attributes in a way they haven't been built for

Thus, always make sure what you're using (by reading W3C / Mozilla documentation).

  • For example, 99% of navigation menus shouldn't have menu, menubar or menuitem roles, instead they only should have the navigation role. (here's why)

Testing accessible web

Note: Automated tests can only test for some common scenarios and practices. Unfortunately, they can't i.e. emulate a blind person and ask if it "sees everything that it should see".

Word on differences in preferred a11y patterns

All those patterns "when to use X" are quite fluid and often based on many different docs, which sometimes give different opinions.

Furthermore, there's a few different screen readers on the market and they have their own ways to read through the content (they often don't do what W3 docs say they should do!).

In moment of doubt, use your best reasoning. Also nevertheless, stick to offical W3 docs (and native browser behaviour) as much as possible. It's better to match officially recognized specs (that screen readers will probably sooner or later support anyways), than just one tool but not all the others.

Also try to test manually (i.e. in ChromeVox) once in a while, instead of just relying on theories and automated tests.

Related articles

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment