wxWidgets Logo



Building Accessible Applications

Accessible apps must be:

  1. Completely and usably keyboard accessible
  2. Compatible with operating system themes
  3. Compatible with 3rd party assistive technologies, such as screen readers, screen magnifiers and voice dictation software
  4. Be usable by people with motor and cognitive impairments. This may mean having a way to slow down or stop animation and moving targets.

UI Designers

When writing up a spec:

  1. Involve accessibility in the process. Many designs can be improved when accessibility is considered.
  2. Don't require fast timing or fast decision making by the user. Animation, flashing, blinking, etc. should be optional, and there should be a pause feature.
  3. Where possible, do not invent new widgets when a standard widget will do the job, unless it's truly adding innovation or is a must for a different look and feel. If you do, spec out standard keyboard support for it. In addition, it may be necessary to implement accessibility API support for the widget.
  4. Imagine how a keyboard user will use your feature. Is your feature for clickers? Does it require drag and drop? Is it visual/random access? Can it also be useable by users that can only take in information sequentially?
  5. Imagine how your feature might be used by someone with limited screen real estate. This could be a PDA user or someone with low vision.
  6. Ensure that color alone is not used to present information -- I'll bet you already knew that :)
  7. Avoid small targets which are difficult to see and click on.
  8. Assign underlined Alt+letter mnemonics for all buttons, checkboxes, radio buttons, menu items, and any other controls with a label. The only UI elements that don't receive underlined accesskeys are list/tree items, the actual tabs in tabbed dialog property sheets, static description text, OK/Cancel buttons and group box headers. It's much easier to add these underlined accesskeys as you check code in than to go back and retrofit.
  9. For selectable lines in a table or tree with multiple checkboxes per item, make sure to have a way to toggle each checkbox using context menu options. Otherwise, keyboard users won't be able to toggle the checkboxes individually -- it would be impossible to know which checkbox should be toggled when a spacebar is pressed on one of the list items.
  10. Every radio button and checkbox must have a text label. This is true even when there is a combo box, text field or other control associated with the radio button. Otherwise keyboard navigation will not work properly, and it is sometimes impossible to see if the radio button has focus.
    This is incorrect:
    This is correct:
    Name of audio file:

UI Engineers

While writing code, and before checking in:

  1. Where possible, do not invent new widgets when a standard widget from wxWindows will do the job, unless it's truly adding innovation or is a must for a different look and feel. If you do, make sure it uses standard keyboard support for each platform. You will also probably need to implement accessibility API support for the widget.
  2. Make sure that there is a default button for each dialog, by using mybutton->SetDefault();. On Windows/*nix, the enter key should fire the default button if another button is not focused. On OS X, Enter should fire the default button no matter what is focused.
  3. Make sure the Escape key cancels your dialogs. Do this by using wxID_CANCEL or wxID_NO for the ID of the "Cancel", "No" or button. Similarly, use the wxID_OK and wxID_YES for your "OK" and "Yes" buttons. Escape key should also work to stop the current operation, if you are providing a progress bar and a stop button.
  4. Add keyboard accelerators to new menu items, if a fair number of users will make use of this feature more than say, 50 times. If there is a similar feature in another popular app, try to use the accelerator people are already accustomed to (such as Ctrl+R for reply to email).
  5. Support standard keystrokes. There are differences between the standard keystrokes for Windows and the standard keystrokes for OS X. For example, we need to support the context menu (VK_APPS) key Microsoft context menu key and Shift+F10 on Windows, while Mac provides Control+Space to open a context menu.. Use EVT_CONTEXT_MENU to capture all of the different ways context menus are generated, rather than just looking for right button clicks. If the event is returned with coordinates of -1, -1 then it was generated from a keystroke.
  6. Focus and tab navigation:
    • Test with all target platforms, when implementing new features and dialogs, because the keyboard navigation rules are different. On OS X, test with fully keyboard access both on and off.
    • Verify that all interactive elements are tab key navigable on Windows/*nix, or when "full keyboard navigation" is turned on in OS X (Ctrl+Fn+F1 to toggle).
    • Make sure there is a sensible initial focus on all top level windows. On Windows/*nix, this is the first control which isn't a notebook tab. On Mac, it should be the default button,
    • Use the wxTAB_TRAVERSAL window style for any window that has more than one focusable child, otherwise a strange tab order will result in MS Windows. You don't need to use wxTAB_TRAVERSAL on the actual controls to make them tabbable - the bool AcceptsFocus() method supports that.
    • Be careful of extra focus events that misdirect assistive technoglies. Also, if the focus isn't going where you expect, try setting a breakpoint in wxWindow::SetFocus() to see where it's coming from. Sometimes SetFocus() is called by another method, such as Raise() or Show().
    • Ensure a logical tab order (left to right, then top to bottom), and that shift+tab goes exactly in the reverse order.
    • Verify that no spots in the tab order are missing visible focus. For example, this can happen if you create a checkbox without passing an associated label to the constructor, instead using a separate static text for the label.
    • Make sure the tab order wraps, and stays consistent the second time through.
  7. Inherit from root custom widget classes -- if you really need a custom widget. If the existing classes don't provide the exact behavior you need, inherit from one of them so that you get the accessible behavior for free.
  8. Watch out for mouse event listening code. If a piece of code you're writing is doing something specific with the mouse, then it probably needs specific code to handle the keyboad as well, and will require extra accessibility testing.
  9. Keep radio buttons sequential. If a group of radio buttons is intended to be part of the same group, make sure they get added to the dialog together. Otherwise, the user cannot use the arrow keys to select all of the choices.
  10. Watch out for non-focusable widgets. For example, the clickable column headers of a sortable table. if you see a situation like this -- an alternative keyboard path to the feature will be required (in this case, perhaps a "Sort By" menu item).
  11. All images or buttons with images require text. Make sure they have a tooltip, and or use SetLabel() to give them a name, even though it's not visible on the screen, so that a screen reader user can know what they are. This includes toolbar and status bar buttons.
  12. Watch out for owner drawn or purely graphical menu items. For example, a "Rate this song" drop down menu which uses a number of graphical stars for each menu item -- no text. One way to fix this is by providing an alternative text menu when a screen reader is present -- see the next item for details on how to do this. Another way to fix it is to include both graphics *and* text in the menu item. Finally, it can also be fixed by creating a wxAccessible class for the menu item.
  13. As a last resort, check for a screen reader, and present an alternate text control or UI. For example, you could provide a text input instead of a custom slider, or add text to menu/list items where graphics were used (for example a checkbox graphic in a check list box). This is done on MS Windows with the following code:
        if (wxSystemSettingsNative::GetMetric(wxSYS_SCREENREADER_PRESENT))
            { /* screen reader is present */ }
  14. Avoid hardcoded color values. Use wxSystemSettingsNative::GetColour (color_constant) to get the appropriate system color. If you must hardcode the color value, test for the OS's high contrast theme like this:
    #define HIGHLIGHT_COLOR  (wxSystemSettings::isContrastThemePresent? \
                                wxSystemSettingsNative::GetColour (wxSYS_COLOUR_HIGHLIGHT) : \
                                wxColour(112, 147, 191))
  15. Don't use hardcoded sizes, like 23 pixels, and ensure your UI scales correctly
    • Hack in a change to make the window resizable (add wxRESIZE_BORDER to the style flags), and test what happens when you resize the window.
    • Test on OS X - it consistently uses a larger font size
    • On Windows, test with the high contrast theme. You can turn it on before launching wxWindows on by hitting left-alt + left-shift +prntscrn. The first time, you should check the settings for it by hitting the "Settings" button instead of "OK", to make sure that Windows will pick a larger font. Using the high contrast them is also a good way to make sure that you haven't incorrectly hardcoded color values (see above).

Accessibility API Strategy

For custom non-native widgets, it is sometimes necessary to support accessibility APIs. The wxAccessible and wxWindowAccessible classes provide a layer of abstraction when implemnenting these APIs, although MSAA/Windows is currently the only native accessibility API supported by these wxWindows classes. Hopefully that will change soon -- as of 2004, the accessibility stories on *nix and OS X are still in the early stages.

If you are designing a control that manages focus for its own windowless children, or if you are using multiple images within the control to render useful information (such as checklistbox, which uses images for the checkboxes), then you probably need to use the wxWindowAccessible class. Make use of the wxWindows accessibility API documentation to do this. Don't forget to fire accessible focus events and test with assistive technologies.


Quick Links

Hello, world!
Stable manual
Latest manual
Change log


Mailing Lists
wxCode (Add-ons)


New ticket





Buy it From:


Site design and update scripts by Kevin Ollivier, with special thanks to Brad Anderson for his improvements to the sidebar, intro table and navbar designs, Bryan Petty for the new wxWidgets blocks graphics and logo text, and to the wxWidgets community for all their helpful suggestions, comments and testing!