Accessibility guide for developers

Jump to: navigation, search

Accessibility is important for our users and most of it is easy to facilitate if we just take into account a few basic ideas and rules. Accessibility is also very difficult in that there are no fixed and universally accepted technical standards that actually work consistently and for all users. This page does not list or discuss specific accessibility problems in MediaWiki. It attempts to focus on technology choices and on Do's and Don'ts, to prevent accessibility problems.

In terms of development, I think this should be our rule book:

  • Try to enable our users (and that means all of them)
  • Try to work around issues of accessibility if that is possible, but not at all costs
  • We should use an approach of Progressive enhancement over that of Graceful degradation.
  • Implement things that are technological sound

We should never forget that we already are considered to be quite accessible.[1][2]

How accessibility works[edit | edit source]

Some important concepts that you should keep in mind.

There are many forms[edit | edit source]

Accessibility is about many things, please consider the following:

  • Something should be understandable: that means textually, visually, logically and in complexity.
  • Some users need a screenreader to interact, but just as, if not more common are: a loupe, a text to speech engine, custom CSS settings, or a special type of keyboard/input device.
  • accessibility != keyboard accessibility != screenreader accessibility

Keyboard navigation[edit | edit source]

We call this keyboard navigation, but what it really means is: Don't rely on a pointer device (touch, mouse)

  • Keyboard navigation is about manipulating the focus and executing actions with your keyboard.
  • Elements that are tabable are focusable, but not everything that is focusable is tabable.
  • Everything you are able to do with a mouse should be possible to do with a keyboard.
  • Keyboard navigation information can be used by screen readers to enhance their experience.

Screen reader[edit | edit source]

  • A screen reader uses a different 'cursor', which usually walks the logical structure of the DOM.
  • The focus tends to follow the screenreader cursor and vice versa, but they are not the same
  • A screenreader uses the 'accessibility' APIs, which you could consider to be a input/output 'view' on top of the normal DOM.
  • ARIA are DOM annotations that enhance or manipulate how the DOM logic is transformed into the accessibility APIs. It is not an alternative to writing proper HTML and Javascript.
  • ARIA is still young, do not rely on it too much. Keyboard navigation and a logical DOM are good fallbacks to have for screen readers.
  • A screenreader is not limited to the logical structure, it's just the default. A screenreader can read what is under the mouse pointer for instance, and VoiceOver for iOS uses a screen curser that is manipulated by thumb positioning and gestures on the touch screen. Do not confuse the visual capabilities of the user with spatial awareness that the screenreader might be able to convey to the user.

Development guidelines[edit | edit source]

There are several standards around accessibility and honestly, almost all of them, although sound on identifying issues, still have significant problems when it comes to technical solutions (They have a high ratio of 'ugly workarounds'). This has been cause of much controversy in the communities. As such, we should identify uncontroversial stuff that we should simply always (or never) do and why. It's much easier to reach certain goals if we separate the uncontroversial stuff from the controversial stuff.

Always[edit | edit source]

Use the proper HTML element 
use the HTML element fitting the function (so you should prefer <button> elements over span, div and a elements)
Logical heading structure 
All pages should always have a logical and consistent heading structure. Headings are one of the primary navigation tools used by screenreader users.
  1. There should be no gaps in the nesting of the heading levels (So no H2->H4)
  2. Headings should be descriptive
  3. Headings should be unique within their own level. (There should not be two H3's with the same content under the same H2 section)
  4. There should be separation between navigation and content
Use a tool like Firefox accessibility evaluation toolbar to easily inspect the structure of all headers.
alt attribute for images 
If an image is decorative, use an explicit empty value for the alt attribute; even better, turn it into a CSS background image.
the image alt usually takes precedence over the title attribute of images and even over the title attribute of links that wrap an image. some tests
title attribute for links 
These are usually shown as the tooltips
Only use titles if they differ from the link text.
Most link titles are not actually spoken by screenreaders, unless the reader has been explicitly configured this way
Always check your colors for sufficient contrast. For text, a higher contrast is needed for smaller text (due to anti-aliasing).
The focus pseudo class 
if you define :hover styling, you usually should also define a :focus style
Focus outline 
do not remove outline from focusable elements unless you define your own outline for the :focus state
Use lang and hreflang attributes 
this makes it possible to select a proper voice, and picks the right spelling correction etc.
Use lists for logically grouped data 
move hlist of en.wp into core to facilitate this?
Keyboard navigation 
The tools should be navigable by keyboard. Please turn that on in your browser if you are a developer.
  1. Use tabIndex: 0 to make elements keyboard accessible, which are not keyboard accessible implicitly (Anything but <a>, <area>, <button>, <input>, <object>, <select>, and <textarea>).
    1. In this case also add a keydown handler responding to Enter (keyCode 13) and space (keyCode 32).
  2. Use tabindex: -1 to remove elements form accessibility. (use this on links that are labels for the action inside an li for instance)
  3. Elements that are implicitly keyboard accessible will forward enter/space keydown to the click handler
Bolding and notes 
If you feel the need to bold something, consider if it is not more appropriate to use a header or a strong/em element
Dialogs etc

When not taking good care of accessibility, dialogs are some of the most inaccessible elements for screenreader and keyboard users. Spend some time on this.

  • The element that opens the dialog should have aria-haspopup
  • The dialog itself should have role=[dialog | alertdialog | tooltip]
  • The dialog should be inserted in DOM order, or aria owns/controls needs to specify this relation between opening element and dialog
  • When opening the dialog, remember last focused element and shift focus to the first focusable tabbable element inside the dialog
  • When the dialog is modal, make it impossible to interact with the rest of the page
    • Capture clicks outside the dialog and ignore them or let them dismiss the dialog
    • Make sure you cannot tab to links or input elements outside of dialog
    • Make elements outside of the dialog unreachable for screenreader, by using aria-hidden
  • Make sure there is a close mode (esc key and a focusable close button with a descriptive title)
  • Closing should return the (keyboard) focus to the original focus point that you stored when you opened the dialog. For screenreaders to return to the same point, be sure to specify the right owner of the dialog, if you have not inserted the dialog in DOM order.
  • Read up: Aria modals, Aria modal dialog, ARIA nonmodal dialog, ARIA tooltips.
WCAG 2.0 guidelines 
follow wherever possible
And it's accompanying documents:

Don't[edit | edit source]

  • There is common advise to use left: -1000px to push something (often the labels of icon buttons) out of the viewport for visual users and still have it in the accessibility DOM. text-indent: -9999px is variant of this. This is BAD advice.
    • This breaks our RTL rendering in several browsers. Specifically in rtl mode it creates a large canvas left of the viewport and scrollbars, much as +1000px would create in ltr mode. (If needed, top: -1000px is preferred over left: -1000px to avoid this).
    • VoiceOver on mobile is unable to use this text as a fallback, since it is a 'positional' screenreader. You cannot move your finger over this text and thus the text will not be read either. (aria-label is often the better choice).
    • Lastly, this enlarges the render surface needed to calculate the final webpage and this can impact performance[1] on mobile devices.
    • Insightful overview of 'hide text offscreen' tricks are given by Jonathan Snook.
  • Things should not be repeated often. If you have a 100 links on a page that can open a dialog, then don't add 100 labels to those 100 links telling the user that it can be used to open a dialog. Telling a user how to use/what to do with the interface is a good thing, doing it consistently is simply annoying. Find a different way to tell it once (an aria-live=polite might be an idea in this case ?).
  • <a href="#">Hide</a> with an onclick handler. VO reads such JS as "internal link Hide". Use a proper button, or <a role="button" tabindex="0">Hide</a>, with 'space' and 'enter' key handlers in the onclick. But no href attribute.

Avoid[edit | edit source]

Unicode symbols 
Most assistive technologies are not good with symbols. Therefore, try to avoid characters such as ↑, →‎ or more complex characters, because many screenreader won't understand them. If they are required, try to wrap with a span element with the title attribute, so that the title attribute can communicate the implicit meaning within the context to the reader.
small fonts 
Legibility is preferred. If you make something so small that it is hard to read, do you even need it to begin with? Also avoid small fonts with low or mediocre contrast values (even if they fall inside the WCAG guidelines, small sizes require more explicit contrast then large sizes, especially with anti aliasing enabled).
unusually large fonts 
If you make text much larger than normal, it can become similarly hard to read (unless it's very short). This applies mostly to body text, or anything that takes up more than a couple lines. But the larger the text is, the more lines it will take up.
tabIndex > 0 
DOM order is preferred wherever possible. DOM order provides context for the actions.

Consider[edit | edit source]

  • Roles
    • If a div or span behaves like an actual button use role="button". also role="dialog" and role="alert"
    • Be careful with roles. For instance, don't add role="button" to a <th> element, since the <th> element has an implicit role="columnheader", which will be overwritten. Instead use role="columnheader button". Similarly for <li> which has an implicit role="listitem"
    • If a button creates a popupdialog, use aria-haspopup.
    • Use aria-labelled-by for contexts where this is not fully logical by itself (so everywhere but for labels in forms and headers in tables).
  • avoid tables for layout purposes. We have some places where they are hard to get rid of (use WAI-ARAI ?)
  • hide stuff:
  • skip/jump to links

Things to discuss[edit | edit source]

  • Roving tabindex vs. aria-activedescendant (roving more compatible, aria-activedescendant more 'compatible?'
  • Usage of . in labels. Ending a label with a dot, causes the screenreader to make a fullstop. See also: bugzilla:24592 where the lack of fullstops creates unintelligible sentences.
  • It seems that setting the ariaProperties with .prop() isn't working in at least Safari+VO. Possible root cause, the DOM is duplicated and .prop only updates the plain DOM object, not the accessibility DOM object ?
  • aria-label is not used by JAWS (14) if you put it on a span (with contents?). The element needs to be either a control/widget or to have a role. TheDJ (talk) 13:44, 18 August 2013 (UTC)

Known bugs[edit | edit source]

See also[edit | edit source]

Papers[edit | edit source]

References[edit | edit source]

  1. WebAIM Screenreader survey listed Wikipedia as favorite #3 of it's respondents group and did not list it in 'Sites to be avoided'.
  2. "The German version of the free encyclopedia Wikipedia is for many users with disabilities, to an acceptable degree, a useful and operable website." - German Language Wikipedia Accessibility Test According to WCAG 2.0 by Third Age Online.

External links[edit | edit source]

Coding conventionsManual:Coding conventions
General All languagesManual:Coding conventions#Code structure · Security for developersSecurity for developers · Pre-commit checklistManual:Pre-commit checklist · Performance guidelinesPerformance guidelines (draft) · Style guideStyle guide · Accessibility guide for developersAccessibility guide for developers (draft)
PHP Code conventionsManual:Coding conventions/PHP · PHPUnit test conventionsManual:PHP unit testing/Writing unit tests#Test_conventions · Security checklist for developersSecurity checklist for developers
JavaScript Code conventionsManual:Coding conventions/JavaScript · Learning JavaScriptLearning JavaScript
CSS Code conventionsManual:Coding conventions/CSS
Database Code conventionsManual:Coding conventions/Database
Python Code conventionsManual:Coding conventions/Python
Ruby Code conventionsManual:Coding conventions/Ruby
Selenium/Cucumber Code conventionsManual:Coding conventions/Selenium
Java Code conventionsManual:Coding conventions/Java
API client code Standards for API client librariesAPI:Client code/Gold standard