Slide 1 of 53

Building Accessible Web Applications:
Challenges, Solutions, and the Future

Options for this presentation:

Presented by:
Steve faulkner
Hans Hillen
TPG Europe

CSUN 2008


The Paciello Group, TPG Europe
  • Accessibility Consultancy
  • Software
  • Web sites
  • Web applications
Steve Faulkner
Technical Director:
Hans Hillen
Accessibility Consultant:

Table of Contents

Examples used in this presentation

Introduction to Web Applications

  • What are the major differences between web applications and traditional websites?
    • No more full page refreshes particular parts of the interface are updated instead
    • Highly responsive
    • Highly dependent on client side scripting
    • Use of custom controls
    • Different use of natively supported controls
    • Customized keyboard interface
    • Use of HTML in a way it was not designed for

Keyboard Accessibility

  • Programmatic focus
    • Using natively focusable controls
    • Using the tabindex attribute and scripting
  • Event handling
    • Dealing with native event handlers
    • Attaching custom key handlers
  • Preventing disruptive changes of context

Programmatic Focus

  • Tells the user agent and assistive technology which element the user is interacting with. This has important advantages:
    • Browser know where keystroke events should fire.
      • Also applies to native key events, e.g. the context key.
    • Screen readers know which element to announce.
      • Only supporting virtual mode is not enough: user will have difficulties interacting.
    • Screen magnifiers know which element to scroll into view.
    • Pseudo styles / customized color schemes can automatically highlight focus.
      • e.g. Windows High Contrast mode, SuperNova or ZoomText

Programatic Focus (Continued)

  • CSS can be used to automatically style focused elements (code example)
    1: a:hover, a:focus, a:active {
    2: color: white;
    3: background-color: black; }
  • Poorly supported in IE:
    • Need to use :active pseudo style
    • Only works consistently for links
    • If The focus pseudo styles don't work, use JavaScript instead:
      1: element.onfocus = highlightFocus;
      2: element.onblur= unHighlightFocus;
      3: ...
      4: addClassName(element, 'highlighted');
      5: removeClassName(element, 'highlighted');

Applying Focus: Native Elements

  • Wrap components or parts in elements that are focusable by default
    • Most commonly used: a, area, input, textarea
      • Choose most appropriate element, e.g. <a> or <input type="img"> where possible.
    • Advantages:
      • Screen readers will perceive the element as interactive.
      • The element is placed in the tab order, making reachable by keyboard (based AT)
    • Disadvantages:
      • Focusable Element does often not make sense semantically (for example: a twisty is not a link)
      • Bulky code / tab order / link list

Applying Focus: tabindex and Scripting

  • The "Tabindex" attribute makes the non-focusable focusable:
    • tabindex="0": Element becomes part of the tab order.
    • tabindex="-1": Element is focusable through scripting or mouse clicks (Example).
    • Advantages (using -1):
      • No cluttering of source or tab order: Event handles can deal with "sub focus"
      • Can force screen reader to announce relevant content
      • Very well suited for ARIA
    • Disadvantages:
      • Screen readers will not necessarily perceive element as interactive,
      • Default actions won't be mentioned.
      • Native key handlers won't work (e.g. Enter, Arrow keys)
      • Technically illegal (but supported by all major browsers)

Key Event Handling

  • Key events
    • have to be assigned for complex controls
    • make the control accessible for keyboard users (including most AT users)
    • have to provide the same functionality as the mouse event handlers do
    • can conflict with native handlers
      • Examples: Arrow keys, Pgup/Pgdown, Enter key.
      • May conflict with your custom defined key handlers. Default action may have to be prevented (example).

Attaching Key Events

  • Through Inline scripting:
    • Bulky code, though sometimes more intuitive to read.
      2: <li class="cmd_newMsg" onkeyup="handleKeyUp(this, event)"> New Message</li>
  • Unobtrusive scripting
    • Cleaner, easier to provide fallback mechanisms, but inactive until the page load is complete and costly for large applications.
      2: <li class="cmd_newMsg menuItem">New Message</li>
      3: JS Pseudocode:
      5: Find all elements that contain a particular class name
      6: for each found element, attach an appropriate event handler

Disruptive Change of Context

  • Examples of a "change of Context" are:
    • A page refresh or a different page being loaded
    • Loss or change of focus to a different element
  • This must never happen when:
    • The user needs time to make a selection or read content
    • Content changes using timeouts or intervals
  • Because:
    • The user will lose focus, and therefore control over the current control.
    • the control will have to be relocated to continue interaction: frustrating and confusing.

Common Examples of Disruptive Context Changes

  • Automated page refreshes to keep content up to date.
  • Timed AJAX calls that replace focus to newly added content or remove the currently focused element.
  • Disruptive onChange handlers (Mostly a problem on I.E.):
    • Keyboard users make a selection one item at a time.
    • Pressing the 'alt' key first solves the problem, but this is not really logical and is not commonly known.
    • onChange example

Change of Context Recommendations

  • Only allow a change of context to occur as a result of an affirmative user action
    • e.g. when submitting a form or clicking on a link.
    • A page refresh is often the expected behavior. If instead the current page is updated with new content, notify or guide the user (more about this later).
    • Always use a separate activation element rather than an onChange handler.
  • When using timed updates, make sure the current focus stays intact.
    • How will you notify your user? This will be covered later

Role, State and labeling of controls

  • Role, state and labeling
    • Native controls
    • Custom controls
  • Providing labeling for interactive controls (including prompts, hints and validation results).
  • Providing descriptive information for (custom) controls, explaining their interface and expected behavior.
  • ARIA to be discussed later.

Role and State Related Information

  • Role: what is the function of the control? Examples:
    • Checkbox
    • Text input
    • Select
  • State: what are its current "settings" or "properties"? Examples:
    • Checked
    • Disabled
    • selected

Some Issues regarding Roles, States and Labels

  • Does every control need a label?
  • Label Placement
  • Implicit versus Explicit Association
  • Use of the label element and title attribute
  • Use of the first option element within a select element
  • Multiple labels for a control
  • Error messages
  • controls within data tables
  • form control groups
  • custom controls

form control label examples - No label

A textfield with no label (Not reccommended)
  • Code:
    2: <input type="text" name="search" />
    3: <input type="submit" value="Search" />
Recommended Solution
  • Code:
    2: <input type="text" name="search" title="Search criteria"/>
    3: <input type="submit" value="Search" />

form control label examples - multiple actions

    • 1: <input type="text" name="searchtext"/>
      2: <input type="submit" name="mail" value="search mail" />
      3: <input type="submit" name="web" value="search the web" />
  • Recommended
    • 1: <input type="text" name="searchtext" title="Search mail or web" />
      2: <input type="submit" name="mail" value="search mail" />
      4: <input type="submit" name="web" value="search the web"
      5: title="search the web: opens in a new window" />

The label placement

Before control; in left-to-right languages, either to the left or immediately above the control. Buttons are self-labelled. Check boxes and radio buttons are special types of buttons, and so the label is part of the button (increases target area), and placed immediately after the control to show the semantic difference.

label Placement
Control label
text, text area, select To the left or immediately above
check box and radio buttons Immediately after the control
buttons self-labelled

Results from an eye tracking study concluded that:

Placing a label above an input field works better in most cases, because users aren’t forced to look separately at the label and the input field. Be careful to visually separate the label for the next input field from the previous input field. But this conclusion needs to be tempered by the power of convention and remembering it is only one study.

Implicit and Explicit Association

  • Implicit Labels
    • 1: label: <input type="text" size="30" name="uname" />
      2: <label></strong>label: <input type="text" size="30" name="uname" /><strong></label>
  • Explicit - Recommended
    • 1: <label for="uname">label:</label>
      2: <input type="text" size="30" id="uname" name="uname">
  • Hybrid
    • 1: <label for="uname">label:
      2: <input type="text" size="30" id="uname" name="uname">
      3: </label>
Implicitly positioned labels do not work correctly in IE6 and lower, and with some screen readers (JAWS 6.2; probably others, but don't know). The for attribute in the hybrid version makes it an explicit association. Implicitly associated labels are made available through MSAA, and are legal according to the specification, making this a user agent problem. Having said that, I don't like implicit associations. Semantically, a label is associated with its form control; it doesn't make sense to say the label is the parent, and the form control is its child. It would make more sense to say that the label is part of the form control, as they are in XForms.

The Option as a label

    • 1: <select name="city">
      2: <option value="-1">choose a city</option>
      4: <option value="1">Birmingham</option>
      5: <option value="2">London</option>
      6: </select>
  • Acceptable
    • 1: <select name="city"  title="choose a city">
      2: <option value="-1">choose a city</option>
      3: <option value="1">Birmingham</option>
      5: </select>

The Option as a Label (continued)

  • Recommended
    • 1: <label for="city">City</label>
      2: <select name="city" id="city">
      3: <option value="-1">Los Angeles</option>
      4: <option value="1">Birmingham</option>
      6: <option value="2">London</option>
      7: </select>
When there's no default option, it's useful to make the first option a label, but it should provide context, and the control should still have an explicit label (or title attribute). Relying on the first option as a label might work in some circumstances, but it soon breaks. For example, if a mistake is made, the user's selections should be retained. They now have a drop-down box whose label is a value that might not be accurate.

Multiple labels for a control

  • first name optional
    • 1: <label for="multi1">name</label>
      2: <input type="text" id="multi1" name="multi">
      3: first name optional
    • 1: <label
      2: for="multi2">name <input type="text" id="multi2" name="multi">
      4: first name optional</label>

Multiple labels for a control (continued)

    • 1: <label for="multi3">name</label>
      2: <input type="text" id="multi3" name="multi">
      3: <label for="multi3">first name optional</label>
  • Recommended
    • 1: <label
      2: for="multi4">name (first name optional)
      3: </label>
      4: <input type="text" id="multi4" name="multi">

Multiple labels and error messages

  • text input with multiple labels - ' input 1' and 'tip: between 1 and 4' Recommended
    • 2: <label for="a">input 1
      3: <span class="formhint">tip: between 1 and 4</span>
      5: </label>
      6: <input class="range:1-4" id="a">
  • text input with multiple labels - ' input 1', 'tip: between 1 and 4' , error icon  and message  'must be between 1 and 4' Recommended
    • 2: <label for="a">
      3: <img id="errorimga" height="16" alt="error" src="error.png">
      4: input 1
      5: <span class="formhint">tip: between 1 and 4</span>
      7: <em class="errortext" id="errortexta">must be within 1 and 4</em>
      8: </label>
      9: <input class="range:1-4" id="a">

Use of hidden labels

    • 1: .hidden {
      2: position: absolute;
      3: left: 0;
      4: top: -999em;
      5: width: 1em;
      6: height: 1em;
      7: overflow: hidden;
      8: }
  • Recommended
    • 1: <input type="text" id="search3" name="search3" title="search criteria">
      3: <input type="submit" value="Search">

Labelling of form controls in data tables

Product order form
code item quantity price
123 pencil $1.00
124 pens $1.50
  • 1: <td>
    2: <label class="hiddenlabel" for="q1">quantity of pencils</label>
    3: <input type="text" id="q1" name="q1" size="3" value="0"></td>
  • Recommended
    1: <td>
    2: <input type="text" name="q1" size="3" value="0" title="quantity of pens"></td>

Labels increase click area

  • over 35
    clickable area is 400px

  • clickable area is 1293px
  • I agree

Grouping: fieldset and legend elements

  • Personal Details
  • 1: <fieldset>
    2: <legend>Personal Details</legend>
    4: <label for="t6">Title</label>
    5: <select name="ddlTitle">
    6: <option>Mr</option>
    7: <option>Ms</option>
    9: </select>
    10: <label for="t1"> First Name</label>
    11: <input type="text"id="t1" name="txtFirstName">
    12: <label for="t2">Middle Name</label>
    14: <input type="text"id="t2"cname="txtmiddleName">
    15: <label for="t3">Last Name</label>
    16: <input type="text" id="t3" name="txtlastName">
    17: </fieldset>

Grouping: fieldset and legend - continued

Search This Site
filter by
1: <fieldset>
2: <legend>Search This Site</legend>
3: <label for="searchfor">Search for</label>
5: <input id="searchfor" name="searchfor" type="text">
6: <fieldset>
7: <legend>filter by</legend>
8: <input type="radio" id="a" value="1"> <label for="a">television</label>
9: <input type="radio" id="b" value="2"> <label for="b">radio</label>
11: <input type="radio" id="c" value="3"> <label for="c">cinema</label>
12: </fieldset><input type="submit" value="search">
13: </fieldset>

Spin control example

  • Prompt labelling
  • Providing role and state information
  • Spin control
  • 1: <label for="spin">Spin:</label>
    2: <input id="spin" size="3" value="0" maxlength="2">
    4: <input id="spinup" type="image" alt="increase value" src="spintop.png">
    5: <input id="spindown" type="image" alt="decrease value" src="spinbot.png">

Collapsable panel example

  • Prompt labelling
  • Providing role and state information
  • Collabsable panel
  • 1: <div id="slide">
    2: <input
    4: style="background: url(closefocus.gif) #ccc no-repeat 0px 50%; height: 216px"
    5: type="image" alt="close panel" src="transparent.gif">
    6: </div>

Slider example

  • Prompt labelling
  • Providing role and state information
  • Slider
  • 1: <div class="slider">
    2: <input id="thumb" title="effectiveness, between 0 and 500"
    3: type="image" alt="effectiveness" src="thumb.gif">
    4: <label id="lbl" for="thumb">effectiveness 
    6: <span id="result">0</span>
    7: </label></div>

tree control example

  • Prompt labelling
  • Providing role and state information
  • tree control
  • 1: <li class="firstclosed"><a class="branchnode collapse" href="#">
    2: <img alt="collapse folder" src="node.png"></a>
    3: <input class="treecheck branchcheck" id="tr1"
    5: title="select all children of item1" type="checkbox">
    6: <img class="branchicon" alt="opened folder" src="folder.png"> item1

Dynamic Content

  • Content that changes after the page has loaded without using a page refresh
  • Dynamic Updates: user initiated and independent
    • Can the user access the updated content?
    • Is the user aware that content is updated?

Screen Reader Modes

  • Browse Mode (virtual buffer):
    • User are provided with a large range of functionality to navigate page content:
      • By paragraph, form control, heading, link (visited, unvisited) list, list items, frames, tables, They can interrogate relationships between data and headers in tables, expanded forms of abbreviations and much more...
      • The user can activate links and some form controls (differs between Window Eyes and JAWS).
      • What the user cannot do is input characters into text inputs or text areas, and interact with select elements.

Screen Reader Modes (continued)

  • Forms Mode (browse mode off):
    • When the virtual buffer is not in use the user can only navigate through a document to focusable elements via the tab key.
    • Access to text is limited to "read all' functionality.
    • Most of the advanced content navigation and interrogation functionality is unavailable.

Independent Update Example

  • This Independent Update Example contains content which is updated to a single heading element a few seconds after the page loads.
    • Older screen readers will not update their buffer: instead they will keep reading the "stale" content that is no longer there.
    • A screen reader buffer update can be triggered by user input. JAWS (pre 7.1) and Window Eyes update the virtual buffer in response to the user pressing a key when interacting with a control or link. If the control or link has some scripting associated with it that changes content on the page and that change occurs before the buffer update finishes, then the changed content will be available to the user.
    • Newer versions of JAWS (7.1 and higher) are more successful in in detecting changes without depending on user input.

Updates and latency

  • User key press: Update is initiated if content itself is updated before the buffer update occurs (e.g. 600milliseconds).
  • If the content takes too long, the buffer update will be complete before the actual content has occured: the new content will not be perceivable.
    • This issue is one of the primary reasons why AJAX is considered inaccessible.
    • From version 7.1 JAWS started to listen
    • Now if it detects changes in page content it updates the virtual copy
    • But it is not perfect, it does not detect all content changes
    • Examples: title and alt attribute content changes
    • Update buffer method example
    • The latency issue does not occur when users are not in "browse mode" as they are interacting directly with the content in the browser.
    • But users access to content is severely restricted.

Alternative access to dynamic content

  • Current methods to provide access to dynamic content are limited by the AT
    • Provide alternatives: Stock Prices Example
    • "Live Regions" will most likely provide an acceptable solution, and are covered in the next section.

Further Reading on Dynamic Content

Accessible Rich Internet Applications: ARIA

  • Problem: Web applications pretend to be desktop applications, but are in fact HTML pages.
  • Available elements in HTML are not sufficient for rich interfaces, as there are no treeviews, toolbars, menus, tab panels, tri-state checkboxes, etc. in HTML
  • Rich controls are often put together using focusable controls, CSS, JS and images.
    • It looks like a treeview.
    • If done correctly, it can feel like a treeview.
    • For a screen reader, it will never be a treeview.
    • The role and state information has to be described manually, and is not programmatically perceivable by AT .

How ARIA Solves the Problem

  • Solution: ARIA roles and states allow developer to add 'semantic sugar' to a custom widget, even if there is no semantically correct element available.
    • ARIA provides (amongst other things): Roles which describe what type of widget an element is portraying, (e.g. "menu", "treeitem", "sliders" or "progressmeter")
    • Roles that can describe the structure of a web page (e.g. "main navigation", "search", etc ).
    • Information about the widget's state (e.g. the current value of a slider, or whether a menu item has a submenu)

ARIA: How it works

  • The developer applies "role" and "state" attributes to cutom widgets
    • One element generally has one role, can have multiple state values
  • Role / state information is mapped by the browser to the operating system's Accessibility API (e.g. MSAA, ATK, Iaccessible2)
    • The AT perceives the widget as if it were a desktop widget, providing all necessary cues and state updates.
  • For ARIA to work as intended:
    • The control must be focusable and keyboard accessible Can be achieved by setting tabindex to -1.
    • ARIA will make sure the AT perceives the element in a semantically correct manner.
  • The AT should run in non-virtual mode: it should not consume keystrokes.

ARIA Support

  • Browsers
    • Supported by Firefox 2 (better in 3)
    • Opera is working on support
    • Not supported by IE (yet). Technically speaking AT should still be able to use ARIA in IE by using the DOM.
  • AT
    • JAWS 7.X and higher: Partial support
    • Window Eyes: Partial support
    • ZoomText: compatible.

How to apply ARIA

  • 'Role' and 'State' Attributes can be added in both XHTML and HTML files.
    • FF3 supports built in attributes.
    • Older versions require namespaced attributes, meaning:
      • The document has to be served as valid XHTML, and the namespaces have to be defined:
        2: <html lang="en" xml:lang="en" xmlns=""
        3: xmlns:wairole=""
        4: xmlns:aaa="">
      • The namespaced attributes have to applied in the DOM after page load. (look for classnames, apply attribute, using setAttributeNS().

ARIA Live Regions

  • Modern Solution for AJAX /DHTML update notification problem.
  • Currently only supported by Firevox (open source screen reader for Firefox).
  • Question: Should users be informed of the change, and if so, when?
    • Certain changes are trivial and should be ignored, e.g. the changing seconds in a clock.
    • Other changes are more important and should be spoken immediately or when convenient.

Marking Up Live Regions

  • The developer tells the AT which parts of the content are likely to change, either over time or as a result of a user action.
  • This is done by specifying the following ARIA properties:
    • 'live': Whether the element is a live region, as well as the level of 'politeness' the AT should use when announcing the change.
    • 'atomic': Whether the whole region should be announced, or just the part that changed.
    • 'controls', 'labelledby' and 'describedby' describe the relationships between a live region and its trigger

Politeness Levels

off (default)
Do not speak this region
Speak this region when the user is idle
Speak this region as soon as possible
Speak this region RIGHT NOW

Levels can be overridden by the user

ARIA resources

Slide 53 of 53

Wrapping Up