410 likes | 730 Views
Top 10 accessibility obstacles in web-based applications … and how to avoid them!. Candace soderston , ph.d . user experience consultant. Accessibility: a quick recap. An aspect of design A code architecture standard Enabling all people to use it
E N D
Top 10 accessibility obstacles in web-based applications … and how to avoid them! Candace soderston, ph.d.user experience consultant
Accessibility: a quick recap • An aspect of design • A code architecture standard • Enabling all people to use it • Focused on Disabilities visual, aural, vocal, physical (mobility) … and cognitive senses. 2
What I’ll cover today: • Baseline Evaluation - research conducted for Kuali Rice* project in 2012 (at University of Washington) • Common mistakes found in interactive web applications • Root causes & how to fix: • Tables • Tabs • Error messaging * See http://www.kuali.org/about and https://wiki.kuali.org/display/KULRICE/Rice+Accessibility
Web applications vs info pages All the interactivity of a desktop application • Web Content Accessibility Guidelines 2.0 (WCAG 2.0) • The current standard, since 2008 – sets the baseline, for electronic information • Accessible Rich Internet Applications (ARIA) • Enables accessible richer interaction… with Ajax, HTML, JavaScript, and other technologies • Is the candidate recommendation to update the standard –like a beta, it is the move into implementation phase & usage feedback • Is already supported by most browsers (you don’t have to wait for the full standard - ARIA tags are ignored on older browsers, they don’t break things)
Full Interactivity in web apps – examples: Data entry fields, select controls, date-pickers, add-delete-save actions, auto-totals …
So … What we did and Why • What we did: • Evaluated the 2011 product & reported status • Designed/architected solutions • Why: build accessibility into the user interface framework, so applications can inherit the benefit: • Accessible widgets and controls • Accessible templates where there is no widget or control • Accessibility guidelines & education where there are no templates
The Heuristic Evaluation • Run acode checker (see http://www.w3.org/WAI/ER/tools/) • Navigate through the UI with keyboard only (no mouse). • Change to high contrast setting. Change to low DPI/large font setting (200x). Try screen magnifiers. • Navigate through the UI with a screen-reader (can you turn off the monitor & still find your way around?). 7
Baseline Evaluation • We evaluated on 2 PCs with MS Windows: • 2 operating systems: Vista and XP2 • 2 browsers: Firefox 5.0 and Internet Explorer 8 • 2 Screen-readers: • JAWS 12.0 • NVDA • 2 DPIs - native and 200% (MS recommends changing DPI rather than resolution) • 2 contrast settings – regular and high contrast (white on black) • 1 MAC with Apple OS X: • 2 browsers: Firefox 5.0 and Safari • 1 screen reader: VoiceOver • 2 screen resolutions: 1440 x 900 and 800 x 600 • 2 contrast settings: regular and high contrast (white on black)
Common Mistakes Found (to avoid!) • Missing language & doctype tags • Missing “skip to main content” links • Missing page titles • Head level problems (e.g. too many H1s, missing levels, & used for links) • Titles or long descriptions needed on some links • Opening new browser tab not “pre-announced” to user • Missing or insufficient visual indication of focus • Images of text used in some active UI elements, not just in branding • Confusing or missing focus order (keyboard navigation) • Tables & Tab structures missing semantic markup (see appendix!) 9
Common Mistakes Found (continued) • Missing language & doctype tags • Missing “skip to main content” links • Missing page titles • Head level problems (e.g. too many H1s, missing levels, & used for links) • Titles or long descriptions needed on some links • Opening new browser tab not “pre-announced” to user • Missing or insufficient visual indication of focus • Images of text used in some active UI elements, not just in branding • Confusing or missing focus order (keyboard navigation) • Tables & Tab structures missing semantic markup – we’ll look at these next! 11
Adaptations needed to make Accessible … Tables – 2 examples Tabs – 1 example (with an HTML & ARIA variation) Error Messaging – 1 example The “Deeper Dives” – Tables Tabs Errors Thanks go to Hans Hillen from the Paciello Group, who consulted with us on the code semantics.
1. Table Examples - Problem 1 Looks like a single table … but … Imagine a widget that encodes this as 2 tables, one for the column header row and another for the data rows … to make it easier to implement sorting for the data rows (so the column header row isn’t included in the sort). To sighted people it looks like a single table, but … it could be a navigation nightmare for screen-reading users! 13
Table markup Example 1 If Widget = 2 tables: If 1 table is not possible, ARIA can “fix” incorrect table structure. • Wrap a single <div role=”grid” aria-readonly=”true”> around both tables. • Add row = ”presentation” to each individual table element. • Add appropriate role to elements in each table. Looks the same, with correct semantics! AFTER (with ARIA tags): <div role="grid" aria-readonly="true”> <table role="presentation"> <tr role="row"> <th role="columnheader”>Account Number</th> <th role="columnheader">Account Name</th> <th role="columnheader”>Fiscal Officer ID</th> </tr> </table> <table role="presentation"> <tr role="row"> <th role="rowheader">234235245</th> <td role="gridcell">Expenses</td> <td role="gridcell">235</td> </tr> <tr role="row"> <th role="rowheader">769856859</th> <td role="gridcell">Transport</td> <td role="gridcell">237</td> </tr> </table> </div>
Table Examples – Problem 2 Multiple interactive elements can be placed within a table cell – all of them visually associated with a label (e.g., “Travel Account Number”).e.g.: • Input field • Inquiry icon • Lookup icon • Help icon • Informational text • Constraint text How Is this semantic relationship encoded in the mark-up, so that screen-readers can interpret and convey this?
Table markup Example 2 A Fieldset and legend Tags can be used to associate multiple controls that apply to the same user input field. (To prevent visual clutter, the fieldset and legend can be hidden visually.) HTML: <tr> <td>Travel Account Number</td> <td> <fieldset class="hidden"> <legend>Travel Account Number</legend> <input type="text" title="number" /> <input type="image" alt=”Direct Inquiry” src="/krad/images/book_open.png"/> </fieldset> <span id="991_comp1_constraint_span" class="constraint"> Must be 10 digits </span> </td> </tr>
Table markup Example 2 B Oryou can assign an ARIA group role to a div to associate multiple controls that apply to the same user input field ARIA: <tr> <th><a href="#"><span class="offScreen">Travel Account Number: </span>236</a></th> <td id="rowLbl1">Travel Account Number</td> <td> <div role="group" aria-labelledby="rowLbl1" aria-describedby="55_instructional_span"> <span id="55_instructional_span" class="summary"> Enter your travel account number or select the inquiry icon to find it. </span> <input type="text" title="number" aria-describedby="991_comp1_constraint_span" /> <input type="image" alt=”Direct Inquiry” src="/krad/images/book_open.png"/> <span id="991_comp1_constraint_span" class="constraint"> Must be 10 digits </span> </div> </td> </tr>
2. Accessible Tab Structures Problem: Items that visually appear to be tabs, but are not marked up appropriately in the code! How does a non-sighted user know they are tabs? … so how to navigate through the overall site content?
Pros / Cons of “vanilla” HTML vs ARIA tab markup (See reference on slide 12.)
Recommendations • If you are going to refresh the entire page content (move to a different page) use HTML markup for tab controls – Tab example A (which follows). • For tab controls on a page that don’t apply to the entire page (e.g., they apply to a section of a form), use ARIA markup (when it is not OK to refresh the entire page & it is OK to work only in Forms mode) – Tab example B.
Tab example A: Start with a Traditional HTML tablist <ul> <li> <a href=”#”>My Dogs</a> </li> <li> <a href=”#”>My Cats</a> </li> <li> <a href=”#”>My Birds</a> </li> </ul> <div> <h2>My Dogs</h2> … </div> <div class=”hidden”> <h2>My Cats</h2> … </div> <div class=”hidden”> <h2>My Birds</h2> … </div> • The tab group is an unordered list (<ul>), preserving the grouped structure for technology that is not ARIA compliant. Each tab is a list item in the tab group’s unordered list. • Each tab is also then implemented as an <a> element inside the list’s items (<li>). • The tab panel(s) – the content -- associated with the tabs are placed below the list, in divs. (Note -- whether only the active tab panel is there or all tab panels depends on whether the entire page has to refresh when a new tab is opened, or whether the contents of a new tab panel is already hidden in the DOM / fetched through Ajax)
Tab example A, cont: Additional HTML markup • Place a heading before the tab list, in this example, “My Animals” • If the visual design doesn’t allow for visual headings, this can be hidden off screen. This heading identifies the tab list and becomes a good anchor point to navigate to. • Add tab role and state information, using hidden text(hidden spans) • The span’s text would = “tab” and “tab, selected”. (Code Example on next slide) • As an alternative for the “selected” part, it is also possible to mark the currently selected tab as a plain list item without a link in it (the fact that it can’t be activated in that case indicates that the tab is currently opened). This technique only works if selecting a tab refreshes the entire page (which would move focus to the start of the new page), not if only the tab panel contents are updated. • Update the page title if the tabs change entire page contents • If the individual tabs in a list represent structural (sub)sections of the site as a whole, it can be useful to modify the page’s title to reflect this. For example, in the portal, opening the “Administration Tab” could cause the outer page’s title to change to “Administration page - Kuali Portal”. This can be achieved through a simple javascript call like: document.title=”My New Title”. • Add a skip link (positioned offscreen) after the heading and before the tab list, if there are many tabs (eg, if 8 or more) Allows users to move focus past the list rather than to have to tab through each item
Tab example A, continued: Additional CSS & HTML markup HTML:<h2 class=”offScreen”>My Animals</h2><ul> <li> <a href=”#”>My Dogs <span class=”offScreen”> Tab, selected</span></a> </li> <li> <a href=”#”>My Cats<span class=”offScreen”> Tab</span></a> </li> <li> <a href=”#”>My Birds<span class=”offScreen”> Tab</span></a> </li></ul> <div> <h3>My Dogs</h3> …</div><div class=”hidden”> <h3>My Cats</h3> …</div><div class=”hidden”> <h3>My Birds</h3> …</div> CSS: .offScreen {position:absolute; left:-10000px;top:auto; width:1px; height:1px;overflow:hidden;}
Recommendations continued For tab controls on a page, that don’t apply to the entire page (e.g., apply to a section of a form) … … use ARIA markup (when it is not OK to refresh the entire page & is OK to work only in Forms mode). Next – Tab Example B – an ARIA tablist!
ARIA Tablist structure • Add ARIA tags to the previous HTML • Manage keyboard and tab order • Manage tab activation
Tab example B: An ARIA tablist In addition to the HTML markup: • On the unordered list tag (<ul>), add: • Role="tablist” • Give the tablist a title. This can be done in either of these ways: • role=”tablist” title=”title goes here”> • Create an HTML label element & point its “for” attribute to the tablist container. • Aria-labelledby="<id of the label text element (whether is is visible or not>". (This could be a hidden heading preceding the tablist) • On the list items (<li>), add: • Role=“presentation” (a tablist should have tabs, not list items, as children, so this role hides them) • On the <a> element inside the list’s items (<li>), define these attributes: • Role="tab" • Aria-selected="true/false" (set to true for the tab that is currently selected, false otherwise) • Aria-controls="<id of corresponding tabpanel>” • On the divs following the tablist, add: • Role="tabpanel" • Aria-labelledby="<id of associated tab element>" • Aria-expanded=”true / false”(depending on whether the tab panel is currently expanded or not) • Aria-hidden=”true / false” (depending on whether the tab panel is currently visible)
But With ARIA markup, we’re not done yet! We need to manage the keyboard & tab order! • The tab list should take up one stop in the tab order. • This tab stop should be to the currently active tab. (To navigate between tabs, typical keyboard users would use the 4 arrow keys as well as the Home, End,PgUpand PgDn keys.) • This "single tab stop" approach can be implemented in ARIA in one of two ways (discussed further on next slides): • Roving Tabindex • ARIA-ActiveDescendant
TAB Example B1: Managing ARIA Tab order with a Roving Tabindex: • Each tab in the tab list has a "tabindex" value. • For the tab that is currently selected, the tabindex value is "0" • All the other tabs have a tabindex value of "-1" (i.e. they are skipped in the tab order but still focusable). • Whenever the selected tab is changed (e.g. by using the arrow keys or clicking on it with the mouse), scripting is used to move focus to that tab, and update the tabindex values for all tabs to reflect the new situation (the tab that used to have tabindex="0" now gets a tabindex value of "-1", and the newly selected tab gets tabindex="0"). • With this approach it's very important to ensure there is always at least one tab with tabindex="0", otherwise the entire tablist would become unreachable by keyboard. In addition to managing the tab order, there are two ways to activate the selected tab & those will be discussed after option 2.
Tab Example B2: Managing ARIA tab order with Aria-activedescendant: • The tablist itself is made focusable (i.e. the <ul> element gets tabindex="0"). • The focused tab is then indicated by adding an aria-activedescendant attribute to the tablist. • The value of the aria-activedescendant attribute is the ID of the tab element that was selected. • When the selected tab changes, the only thing that needs to be updated is the value of that attribute so that it targets the newly selected tab. • If this approach is followed correctly, the browser and screen reader will perceive the tab referenced by aria-activedescendant as being focused. In addition to managing the tab order, there are two ways to activate the selected tab. Next we’ll talk through the two ways to activate a new tab in an ARIA tablist.
And – There are 2 ways to activate an ARIA tab: Activation Option i: Clicking on a tab loads a new page • When navigating the tabs with the arrow keys, it moves focus, but does not automatically open the tab. • To activate a focused tab, the keyboard user presses the Enter key, after which a new page loads. • Note that it is very important to correctly set the "aria-selected" tabs to true or false for all tabs (a screen reader user needs to hear which tab is currently selected and which ones are not). UX recommendation is to use activation option ii, not i, with ARIA tablist: • Use option ii for ARIA tablists (where we don’t want the entire page to refresh). • Use traditional HTML tablists where entire page will refresh, so tablist will work outside of forms mode (see earlier slide with the current pros/cons of HTML and ARIA tablists).
2 ways to activate a new tab, continued Activation Option ii: Clicking on a tab updates just the relevant part of the page through AJAX. The tablistand rest of page stays the same. • If tabs are used to dynamically load content, but focus remains on the actual tab, it's recommended to automatically activate the tab as it is navigated with the arrow key (mouse & keyboard behavior are the same). This behavior is similar to how a tab list works in a desktop environment. Current UX recommendation is to use this activation option where we use ARIA tablists (and be consistent throughout an application). See example code snippet for activation option ii that follows.
Tab example B1: ARIA Tablist with a Roving Tabindexand with Activation Option ii <ul role=”tablist” title=”My Animals”> <li role=”presentation”> <a tabindex=”0” href=”#” role=”tab” aria-selected=”true” aria-controls=”tabpanel1”>Dogs</a> </li> <li role=”presentation”> <a tabindex=”-1” href=”#” role=”tab” aria-selected=”false” aria-controls=”tabpanel2”>Cats</a> </li> <li role=”presentation”> <a tabindex=”-1” href=”#” role=”tab” aria-selected=”false” aria-controls=”tabpanel3”>Birds</a> </li></ul><div role=”tabpanel” aria-labelledby=”tab1” aria-expanded=”true” aria-hidden=”false”> <h3>My Dogs</h3> …</div><div role=”tabpanel” aria-labelledby=”tab2” aria-expanded=”false” aria-hidden=”true”> <h3>My Cats</h3> …</div><div role=”tabpanel” aria-labelledby=”tab3” aria-expanded=”false” aria-hidden=”true”> <h3>My Birds</h3> …</div>
Tab example B2: ARIA Tablist with Aria-Activedescendantand Activation Option ii <ul role="tablist" title=”My Animals” tabindex="0"aria-activedescendant="tab1"> <li role="presentation"> <a id="tab1" href="#" role="tab” aria-selected="true” aria-controls=”tabpanel1" >Dogs</a> </li> <li role=”presentation”> <a id="tab2” href=”#” role=”tab” aria-selected=”false” aria-controls=”tabpanel2”>Cats</a> </li> <li role=”presentation”> <a id="tab3” href=”#” role=”tab” aria-selected=”false” aria-controls=”tabpanel3” >Birds</a> </li></ul><div role=”tabpanel” aria-labelledby=”tab1” <h3>My Dogs</h3> …</div><div role=”tabpanel” aria-labelledby=”tab2 <h3>My Cats</h3> …</div><div role=”tabpanel” aria-labelledby=”tab3” <h3>My Birds</h3> …</div>
Creating Accessible Tabs – Summary of Recommendations • If you are going to refresh the entire page content, use structured HTML markup for tab controls: • The Tab Group is an un-ordered list, and each tab is a list item with an “a:” element within it, which points to a div • The div is placed after the unordered list and contains the tab’s content • Place a heading before the tab list (this can be placed off-screen if you don’t want a visible heading) • Add tab role and state information, using hidden text (hidden spans). The span’s text would be “tab” and “tab, selected” • Update the page title if the tab changes the entire page’s content • Add a skip link (positioned offscreen) after the heading and before the tab list, if there are many tabs (eg, if 8 or more) • If you are going to refresh the content within only a section of the page, use ARIA for tab controls: • Add ARIA tags (roles, label elements, selection state elements) to the HTML markup for tab controls. Add to the unordered list tag, to each list item tag, and to the divs following the tab list • Manage keyboard and tab order with a Roving Tabindex or using ARIA-ActiveDescendant • Manage tab activation using option ii: Update just the relevant tab part of the page through AJAX. The tablist and rest of page stays the same. Selecting a tab will dynamically load content, but the focus remains on the activated tab (mouse & keyboard behavior are the same).
3. Accessible Error Messaging Error Scenario: • User submits complex form (after field-level client-side validation, if any, is done) • Application finds errors in multiple fields on the page, across groups of fields. • How does the user know how many errors there are and then navigate to them? Best practice = • At top of page there is a page-level summary of errors (so that it is early in the screen-reading order) – the summary includes the # of errors in each group that has errors, not the error text. Focus is placed here when application returns errors. • User can jump directly to any of the groups that have errors, because each group in the summary is marked up as a link: • If there are group-level summaries, the focus(link) moves to the group’s summary, and from there the user can jump to any of the fields.(this is recommended) • If there are no group-level summaries, the focus(link) moves to the 1st field that has an error in the chosen group. (Application can implement w/o group summary but this is not recommended) • Every summary (page level and group level) starts with a heading. • The user can get back to the page-level summary using standard shortcuts for moving to top of page, or we can create a custom global shortcut.
Accessible Error Messaging, continued • Example page-level summary, with heading text-variable filled in: <h2 id="pageSummaryHeading" class="errorSummaryHeading">17 errors in form submission</h2> • Example group and field-level error messaging: • Error state indication is placed with the field – see icon and field visual treatment. (Helps low-vision & all users!) • Error text is placed in group-level summary above the group’s fields AND placed in an error tooltip. The tooltip appears contiguous with the field when the user hovers over and when the field is selected. • Try out the behavior in a sample code implementation here!
Accessible Error Messaging, continued • Additional visual indication on the field when user hovers over the error text. • Additional visual indication on the field when the user selects it and can enter data. • Tooltip remains visible with the field while entering the data. • Try out the behavior in a sample code implementation here!
Accessible Error Messaging, continued • Addresses the need to place the error indication and text as close to the field as possible -- helpful for all users and also needed particularly for low-vision users. • Solves the formatting problems we could otherwise create when we place error message text within each field (whether immediately below or to the right), requiring other space to be pushed aside or down: • We don’t know how wide or deep the other aspects associated with the fields and groups will be, how adding the error text will affect the relationship/layout with other field groups on the page. • Placing content inside a form field’s label means that all this content will be announced by a screen reader as the field’s accessible name, rather than as the field’s accessible description or state information. This is too verbose.
Finally – Some Caveats • This is a deep area –requires study and expertise – is not yet fully automatable • There are tools and resources to help • Aspirational target = live partnering with and evaluation by special needs audiences
Accessibility Resources • W3C’s WCAG 2.0 guidelines: http://www.w3.org/WAI/WCAG20/quickref/Overview.php • W3C’s list of code checkers: http://www.w3.org/WAI/ER/tools/ • University of Washington’s Accessibility resources: http://www.washington.edu/accessibility/ • Illinois IT Accessibility Initiative: http://www.itaccessibility.illinois.edu/ • The Inclusive Design Institute at Ontario College of Design in Toronto (http://inclusivedesign.ca/) • The Paciello Group (http://www.paciellogroup.com/) • Kuali Rice Accessibility: https://wiki.kuali.org/display/KULRICE/Rice+Accessibility • Microsoft Accessibility: http://www.microsoft.com/enable/ • Apple Accessibility: http://www.apple.com/accessibility/ • IBM Accessibility: http://www.ibm.com/accessibility/ • jQuery toolkit team (http://jquery.com/) • The Dojo toolkit team (http://dojotoolkit.org/) • Fluid skinning system team (http://www.fluidproject.org/)