Web Accessibility To-Do List for MODx Manager
Evaluation by Paul Bohman using
automated tools such as
FireEyes/WorldSpace by
Deque,
Wave by
WebAIM, but mostly this is a manual
evaluation comparing the actions of the web site against the
Web Content Accessibility Guidelines 2.0 and web accessibility best practices.
Table of Contents
Executive Summary
Accessibility to people with disabilities is critical not only for the
individuals with disabilities themselves — who currently cannot use
the MODx manager — but also for companies hoping to use MODx.
Government entities, in particular, would be legally at risk if they
decided to use MODx because of the non-compliance of the manager interface
with web accessibility guidelines.
This evaluation is still incomplete, but some trends have emerged:
-
Keyboard accessibility:
-
There are many, many places in the MODx manager where a mouse is
required. This makes it impossible for blind screen reader users to
use, because the mouse is not useful to someone who can't see where
to click it. It also makes it impossible for sighted keyboard users
who can't use a mouse, perhaps because they have tremors in their
hands, or have no hands and user a mouth stick, or they have another
similar condition. Many of the dynamic widgets (tablists,
multi-select lists, etc.) need to be enhanced with ARIA attributes
and ARIA-style keyboard patterns to enable effective screen reader
interaction.
-
Keyboard focus management:
-
The keyboard focus needs to follow the action of dynamic scripts
(modal windows, form validation, etc.).
-
Labels and text alternatives:
-
Every active element (links, buttons, etc.) and every important
image-like element (graphics and font icons) needs a text label or a
text alternative. Without a label or text alternative, screen
readers have nothing to read, so users don't know what the elements
are.
There are other issues too, but the above issues are pervasive and need to
be addressed broadly across the MODx manager.
Background Information About Web Accessibility
-
Visual Disabilities:
-
Blind screen reader users need:
- alt text for images, icons, etc.
- labels on form elements
-
full keyboard accessibility of all functionality, including
drop-down menus, tool-tips, tab lists, modals, etc.
-
focus management with dynamic content such as error/feedback
messages, dynamically-loaded AJAX content, etc.
- logical tab order
- valid link and button text
-
good document structure (headings, table headers, lists,
landmark regions)
-
Low vision users need:
- good color contrast
-
easily visible :focus styles, and preferably :hover styles too
-
Color blind users need:
-
information presented in a way that does not depend on color
-
Deaf users need:
-
Transcripts and captions for audio/visual content (not an issue with
MODx manager)
-
Users with motor disabilities need:
- full keyboard functionality (see above under blind users)
-
easily visible :focus styles (some people cannot use a mouse at all,
so they need to know where the keyboard focus is at all times)
-
Users with cognitive disabilities (including common
reading disorders, ADD, and others) need:
-
simplicity in the visual design, organization, processes, etc.
- clear instructions
- good error prevention mechanisms
- good, intuitive error recovery mechanisms
Styles
-
Keyboard visual focus indicator:
-
The visual focus indicator on keyboard focus is either non-existent
in some places or too hard to see. This can be added to
manager/templates/default/css/index.css:
body *:focus {outline:2px solid #00948e !important;}
body #modx-header *:focus {outline:2px solid #fbf5be
!important;}
This will solve the problem nearly everywhere, but additional
styling and/or JavaScript will need to be added to make sure there
is a visible outline around the custom checkboxes. I realize that
this impacts the design somewhat, but having an easily-visible
keyboard focus indicator is a requirement for accessibility, and has
a huge positive impact on people who can't use a mouse. The impact
on mouse users is minimal. They will see it on form fields, but
that's probably a good thing. They won't see it with mouse hover
(though you could certainly add the same styles for :hover, which
would also be good for accessibility, though not as much of a
requirement.)
[NOTE: I just noticed that the above styles only partially work in
Safari and Chrome, presumably due to some conflicts with other
webkit-specific styles in the style sheet somewhere, so additional
work is needed to make the visual keyboard focus indicator
functional in webkit browsers.]
-
Color contrast:
-
The color contrast ratio of the light-colored text in many places
does not pass the WCAG standard of 4.5 to 1 for normal text of 3 to
1 for large text. The color contrast can be analyzed using automated
tools such as FireEyes and Wave.
Login Screen
-
Labels:
-
The "username or email" field needs a <label> tag.
Placeholder text is not considered a valid label.
-
Required fields:
-
Use aria-required="true" on all required <input>
elements. Screen readers will say "required" when reading
to users.
-
Keyboard tab order:
-
The tab order is mostly right, but the language selector in the
bottom left corner is out of order. It should be moved in the source
code so that it is the last thing on the page in the tab order, both
when the login screen is in its default state and when the
"forgot your login" feature is activated. I noticed that
tabindex is used on some of the links and fields. It's best to not
use tabindex with any positive numbers because it overrides the
default browser tab behavior in ways that are often undesirable to
keyboard users (tabindex="0" is acceptable to put
something in the normal tab flow, and tabindex="-1" is
acceptable to make something focusable via JavaScript, but
tabindex="1" or more is not best practice). One problem
with tabindex of positive numbers is that if you forget to add a
tabindex value to a link or form field -- such as the "forgot
your login" link and on the "username or email" field
and the "send activation email" button -- you run the risk
of putting things out proper order, and that is what has happened
here. The recommendation is to simply put things in the correct tab
order in the DOM to begin with and not alter the tab order with
tabindex of positive numbers.
-
Keyboard focus management:
-
When users click on "forgot your login?" the keyboard
focus needs to move to the "username or email" form field.
-
Error/feedback messages:
-
The feedback messages ("User not found...", "The
username or password you entered is incorrect...") need to be
read by screen readers when the page refreshes.
-
Option 1: One way to accomplish this is to
force the keyboard focus onto the error message when the page
reloads. The error message would need to have
tabindex="-1" to effectively be able to receive the
focus via JavaScript. <div id="alert-message"
tabindex="-1">User not found...</div>. The
message should precede the first relevant form field. If the
username/password is incorrect, the message should appear above
the username field. If the error occurs on the "Username or
Email" field (after selecting "forgot password?"
then the error message should appear directly above the
"username or email" field, so that users hit tab once
to go into that field.
-
Option 2: put the error message in the label of
the relevant field, either by putting it in the <label>
tag, or by using aria-label to refer to the message, e.g. refer
to both the regular label and the message:
<div id="alert-message">User not
found...</div>
<label for="username"
id="username-label">Username</label>
<input aria-label="alert-message username-label"
...>
Note that you would want to link the error message for the
"username or email" field to that field directly, not
to the "username" field. You would also want to make
sure that keyboard focus goes to the "username or
email" field and NOT to the top "username" field
on page reload. In other words, make sure you're sending the
keyboard focus to the correct field to match the error, and make
sure the error message is associated with the appropriate field.
-
Also: Set aria-invalid="true" on the <input>
element after the form has been submitted on all incorrect
fields. Screen readers will say "invalid" to let users
know they need to fix the field.
-
Color contrast:
-
The contrast ratio between the blue link text and the grey
background is too low for some users with low vision. The blue text
is also too light even against the white background for
accessibility contrast ratio standards. A possible value is #206e99
-
The contrast is too low on the grey text of the "Language"
label in the bottom left and the "remember me" label. A
possible value for "remember me" would be #757575. A
possible value for "Language" is #575757.
-
The contrast is too low on the teal background color of the buttons
compared to the white text on top. A possible value would be
#007571.
Overall Manager Page Structure
There are no landmark regions or roles specified. Landmark regions help
screen reader users navigate quickly to regions without having to read
through the whole page. Here are the regions I would suggest for the main
manager layout:
<header role="banner">
<div role="search"></div>
<nav role="navigation" aria-label="manager menu"> <!--(for the menu on the left)--> </nav>
<nav role="navigation" aria-label="user and system menu"> <!--(for the menu on the right)--> </nav>
</header>
<ul role="tablist" aria-label="Tree view tablist"> <!--(or come up with a better label for this)-->
<li role="tab">Resources<li><li role="tab">Elements</li><li role="Files">
</ul>
<div role="tabpanel">
<nav role="navigation" aria-label="Resource Tree"> <ul>...</ul></nav>
<nav role="navigation" aria-label="Element Tree"> <ul>...</ul></nav>
<nav role="navigation" aria-label="File Tree"> <ul>...</ul></nav>
</div>
<main role="main">
All of the main content goes here (page edits, snippet edits, dashboard content, etc.)
</main>
<footer role="contentinfo">
(Right now MODx manager does not have a footer, but this is how you would mark it up)
</footer>
Note: You could also achieve the same functional result using only
<div> tags with role attributes instead of the HTML 5 tags plus the
role attributes, but the latter solution is more forward-thinking.
Main Top Menu (the überbar)
-
Tab order:
-
The order of objects in the DOM differs from the visual order. The
way the links are laid out visually, I would expect the order to be:
- MODx/home logo
- search
- content/media/extras/manage
- user menu
- gear/system menu
- help icon
-
The actual order starts with user and goes to the right and then
goes back to the MODx home and across the left menu, which is not
intuitive.
-
Keyboard accessibility:
-
The main drop down menus are not accessible by keyboard. This is a
big problem -- it's a deal-breaker, really -- that affects blind
users and sighted keyboard users, neither of which can use a mouse
effectively. The menu is 100% inaccessible to these groups. The
ideal would be to use an aria-based menu that allows users to tab
into the group (the whole nav/menu group) and then tab past it
without tabbing into the menu items at all, and use the arrow keys
to navigate within the menu system itself. See the keyboard patterns
outlined here:
-
Alt text for images and icons:
- The gravatar image has no alt text
-
The gear icon and help icon need text. Options include:
-
Use visually hidden text that only screen readers can access
(use CSS clip or offscreen text) and hide the icon itself in
case the screen reader tries to read it (it will almost surely
read it incorrectly):
-
<span class="icon-gear icon icon-large"
aria-hidden="true"></span><span
class="visually-hidden">System
Menu</span>
-
Or use role="image" and aria-label:
-
<span class="icon-gear icon icon-large"
role="image" aria-label="System
Menu"></span>
-
Form label:
-
The search field needs a <label> tag, preferably one that is
visible (the placeholder is not considered an accessible label
because it disappears as soon as the keyboard focus enters the
field), but you could also implement a hidden label in this
particular case, because the magnifying glass conveys the idea of
search (as long as the magnifying glass is turned into an actual
submit button and as long as it has text that says
"search").
-
Submit button is missing:
-
Ideally, the form would have an actual submit button so that blind
users know they can submit the form. Blind users don't see the
magnifying glass icon. In fact, the magnifying glass icon could be
turned into a submit button, and you could maintain the same basic
look as the exiting interface.
The Side Tree Panel
-
Keyboard accessibility of tablist/tab panels:
-
The tab panel is not keyboard accessible at all. The main tabs need
to have tabindex="0" on the active tab and
tabindex="-1" on the inactive tabs, and the JavaScript
needs to toggle that value as users select different tabs. You also
need to toggle aria-expanded="true" and
aria-controls="the-id-of-the-tabpanel". See
https://dequeuniversity.com/assets/js/aria/saveform/form2.html
for an example.
-
Icon alternative text:
-
All of the icons (New document, New symlink, etc. and Trash) need
alt text so screen readers know what to say. See "alt text for
images and icons" in the uberbar above for possible techniques.
-
Button role for icons:
-
The icons (New document, New symlink, etc. and Trash) should be
given role="button" or they should be enclosed in actual
<button> tags because they are perform application-type
features, and a button is the appropriate semantic role to convey to
screen reader users.
-
Keyboard-accessible tooltips for icon/buttons:
-
The tooltip should popup when the icons/buttons receive keyboard
focus, and not just with mouseover events.
-
Keyboard accessibility of the button to collapse side bar:
-
The handle to collapse the entire side bar to the left needs to be
keyboard accessible, and it needs to be a <button> or have
role="button" and it must have a label ("collapse
sidebar" for example) to convey to users its purpose.
-
Keyboard accessibility of tree view:
-
Users need to be able to access all items and functionality
(refresh, add new __ here, etc.) in the tree view with the keyboard.
It would be best to implement an ARIA tree menu that allows
navigation with the arrow key. You would tab into the tree object
and then use the arrow keys to navigate within it, including
expanding and collapsing nodes in the tree. Using the tab key would
take you out of the tree, not navigate within it. Tree views are
kind of complicated, but they can be made accessible. You would need
to add ARIA attributes and toggle between various states such as
aria-expanded="true". You would also need to make sure
that the functionality of the expand/collapse icon/triangle is
clear, and that it is separate from the functionality of the page
title itself, which opens the page. See
-
Keyboard accessibility of right-click menu in the tree view:
-
The functionality of the right-click menu needs to be available to
keyboard users. All of the features are available other places, so
this requirement is sort of satisfied already, but it would be best
to make the right-click menu directly available to keyboard users,
rather than make them go through the less efficient routes to the
same features. You could implement a keyboard shortcut such as
alt+enter on links in the menu to activate the right-click menu. To
be effective, though, you would need to tell users that this
keyboard shortcut exists, so you could add a tooltip to each link
saying "Use alt + enter for contextual menu". You would
need to ensure that screen readers also read this text. Particularly
important is the ability to add new items (resources, elements,
files) as children of the item that currently has the focus, since
this is a very common task.
-
Keyboard focus management:
-
When you select a page to edit it, the focus initially goes to the
pagetitle field, which seems logical. I like that. The problem is
that the menu tree loads and refreshes, and as it does so, it
eventually steals the keyboard focus away from that field and puts
the focus on the current page in the tree view. This breaks the
keyboard flow, and if you can't use a mouse, you have to tab, tab,
tab, tab, tab, a lot of times to get back to where you were. Ensure
that the tree view doesn't steal the focus.
Modal Dialogs
-
Keyboard focus management:
- Send focus to modal
-
Ensure that the focus goes to the modal when it is activated. If
it's a simple ok/cancel modal, then the focus should go on the ok
button. MODx seems to do this well in the places I've looked.
-
Restrict keyboard access to the modal while it is active:
-
Ensure users can't tab to links underneath the modal or use a
screen reader to access other elements beneath the modal. One
technique to accomplish the latter is to set everything
underneath the modal to aria-hidden="true". This will
not hide it from visual users, but it will make the content
unavailable to screen reader users, which is what you want in
this case. Use JavaScript to control focus so that keyboard
users can't tab forward or backward (shift+tab) out of the
modal.
-
Completely hide inactive modals (and other similar dynamic
content):
-
Ensure the modal is completely hidden from all users, including
from screen reader users by using display:none on the element if
it is in the DOM already. Be sure to revert it back to
display:none at the appropriate time too, after the user or
script is done with it. So far I haven't encountered any
problems with modals in MODx being read by screen readers when
they're inactive, but it's something to watch out for.
Add/Edit Resource
-
Labels for form fields, buttons, and button-like (scripted)
elements:
-
The "Content" main field needs a real <label> tag
associated with it.
-
The show/hide widget above the right of the Content textarea and to
the right of the tabs (Document, Settings, Template Variables...)
needs a label. Give it a label like "hide Content field"
(for the bottom one) or "Hide page properties" (for the
top one), which should toggle to "show Content field"
after it has been activated. This should probably be a button, so it
could be coded like this:
<button aria-label="Hide Content
field"> </button>
In some ways it would be preferable to have real text in the
button:
<button><span class="visually-hidden">Hide
Content field</span></button>
This text could be visually hidden using CSS clip or offscreen
techniques (don't use display:none, because that hides it from
screen readers too!).
-
In the "Template Variables" pane, when a template variable
has a property like @INHERIT, the text that currently shows up to
the right of the field (e.g. "Value Inherited") needs to
be inside the <label>. You can still style it to be over on
the right side, but don't put it outside the label.
-
Required fields:
-
Use aria-required="true" on all required <input>
elements. Screen readers will say "required" when reading
to users.
-
Keyboard accessibility:
-
The tab interface is not keyboard-accessible. Users need to be able
to navigate to the tab list with the tab key, then use the arrow
keys to navigate the tabs themselves. See
https://dequeuniversity.com/assets/js/aria/saveform/form2.html
for an example of an accessible tablist and tabpanel.
-
The "Uses template" selector:
-
Ensure this widget is fully keyboard accessible so that people
using only the keyboard can switch templates.
-
The Content show/hide widget:
- Ensure keyboard users can tab this control
-
The scripted read-only inputs under the "Settings" tab:
-
The button (and it should be a button) to the right of the
"Parent Resource" field needs to be
keyboard-accessible, and/or users need to be able to type an
integer directly into the field.
-
The button to the right of the "Resource Type" field
needs to be keyboard accessible, and keyboard users need to be
able to select a resource type without a mouse.
-
The button to the right of "Content Type" needs to be
keyboard-accessible and users need to be able to select a
content type without a mouse.
-
The button to the right of "Content Disposition" needs
to be keyboard-accessible and users need to be able to select a
content disposition without a mouse.
-
The "Template Variables" panel:
-
The tablist on the side must be keyboard accessible. See
https://dequeuniversity.com/assets/js/aria/saveform/form2.html
for an example of an accessible tablist and tabpanel.
-
The "Set to default" feature is not
keyboard-accessible. Users should be able to tab to it and use
it without a mouse. NOTE: Be sure to give each of these a
distinct name, so they don't all say just "Set to
default". You want it to say something like "Set
Course ID to default", where "Course ID" is the
name/caption for the template variable. Otherwise users won't
know for sure which button refers to which field, because there
may be several TVs and the placement of the "Set to
default" button could be ambiguous (does it refer to the
previous TV or the next TV?).
-
The resource group panel:
-
This seems to be unavailable by keyboard, but if you cheat and
click with your mouse in the list of resource groups, keyboard
access to the pane is possible, even though access to the
checkboxes is not.
-
checkboxes:
-
The resource group checkboxes are available only with a mouse.
They need to be keyboard-focusable and keyboard-functional (with
enter or space bar).
-
Keyboard tab order:
-
For the most part the tab order is good (for the things that can be
tabbed to), but the "Freeze URI" checkbox is out of order.
It looks like it should be next after "Rich Text" but it
is not.
-
Error messages:
-
When a field is invalid (required field is empty, for example)
onblur, add aria-invalid="true" so that screen reader user
will hear this when they navigate back to the field.
-
When the user attempts to submit the page when there are invalid
fields, move the keyboard focus to the invalid field (even if
that field is in a different tab panel than the current focus),
so that users can find the error and fix it. Make sure the error
message is associated with the field by either being in the
<label> itself or being referred to by aria-labelledby.
Here is a suggestion:
<label>Title*<br>
<input aria-invalid="true"
aria-required="true" ...>
<span class="error-message">This field is
required</span>
</label>
When both the label and the error message are wrapped in the
label tag along with the input itself, the title and error
message with both be read when users focus on the input. This is
a very convenient way of ensuring that error messages will be
read by screen readers. (Note that aria-invalid="true"
applies only after the field is truly invalid; not on page
load.)