Geeks With Blogs
CodeSeeker Just another developer trying to do the right thing

If you have the requirement to make your website accessible, unless you were given that requirement before you began the project, you will probably be converting an existing site. This was my task. After a lot of research, some work with blind users, and working with JAWS myself, here are the recommendations that I am presenting to our development team to make our ASP.NET 2.0 application more accessible. In another post, I will give some more detail about some of the specific solutions we developed.

Of course some of these recommendations are very specific to our website and our design standards. Your mileage may vary, but hopefully you'll find something useful. They are also not particularly organized in an optimal way, so you may need to read later items to know what earlier items mean. There will be more we need to do to make our website more accessible, but these are the items that were agreed upon to implement in this phase.

For a little background, our website is highly forms-intensive, and we make extensive use of gridview controls that allow editing of rows within the grid. We use fieldsets extensively as design elements. It is a secure website with a somewhat controlled, but large (>5000), user base. All of our users use IE. The system has a framework and a main portal page with modules that are available depending on the users access permissions. Currently about half of the modules are in production.

General Guidelines
1. CSS should be preferred for all presentation formatting. It is best to have a unified, consistent CSS scheme, but what is important is how the page renders. For example, specifying Height and Width on controls will render in a Style attribute, and this is OK.
2. XHTML 1.0, HTML 4.01 should be used everywhere. Use an HTML validator and minimize errors. ValidationSummary controls (which render as <div> tags) within a <p> fail validation, but they still render properly and look good.
3. Relative sizing should be used. In general, use “em” for fonts, images, and imagebuttons and “%” for gridview columns (ItemStyle-Width attribute in the templatefield tag) and controls (including width=”100%”).
    a. Be careful that gridview grid lines don’t get shifted over.
    b. For textboxes in grids use height=”100%”. 
    c. For some small textboxes that only take a few characters, it works better to size their width with an “em” value. 
    d. Make sure columns in grids will wrap if text with larger size will push grid to exceed page width. Do not change page width (for now).
    e. If textboxes in grid cells with max length text in them push the grid off the right side of the screen (visible when editing a row, for example), consider using TextMode=”MultiLine”. If you do this though, the MaxLen property becomes useless and has to be handled another way (preferably with a RegularExpressionValidator).
    f. Everything within the page should scale in size when the text size is changed (you can use Ctrl-mouse wheel to change the text size easily) but not stretch the bottom portion of the screen beyond the header width. There will still be a problem for or grids with a lot of controls. 
    g. Lookup controls and the custom images in bulleted lists will not scale. 
    h. Checkboxes do not scale.
4. Add a descriptive alternate text for all graphics, including imagebuttons. Master page logos should read "Our Company Logo", not just "Logo". The alt text for “Add New” buttons for gridviews are the same as the corresponding link text.
5. Set the focus to a logical place after postback. 
    a. For error and success messages, set the focus to MainContent after postback after submit via Javascript. 
    b. When adding or editing a row, set the focus to the first editable field. 
    c. Set focus on the same control if it causes an autopostback (dropdown lists, tabs, etc.). For RadioButtonLists, set the focus to the next appropriate control.
6. Do not use abbreviations. Screen readers cannot distinguish between abbreviations and full words. Acronyms are sometimes read properly if all characters are in upper case.
7. Multi-words should be broken down into their individual words. For example, ShortName becomes Short Name.
8. If tab order does not flow logically, specify tab index for controls.
9. The field name referenced in messages should match the corresponding column or label text.
10. All wording should be as concise and clear as possible, and should be complete sentences and follow proper spelling, grammar, and punctuation rules.
    a. In messages, placing the field name first gives it emphasis.
11. Review all text including error/success messages to ensure conciseness, proper spelling, grammar, and punctuation. JAWS does not have a spell checker. If something is misspelled, it will be misread.
12. Sufficient contrast between foreground and background must be provided. Do not use a graphic background to provide contrast because if the user has graphics turned off, no contrast will be available.
13. On search pages, after clicking the search button and displaying the results, the search panel should collapse to just a link that re-opens the search panel. There are some simpler pages that may not need this feature.
14. Make sure that images used for links are reasonably large, preferably 32 pixels by 16 pixels or larger. Use standard or enlarged font sizes for text links, and avoid using text links that are shorter than four characters in length. Additionally, avoid placing small links close together. (CA DOR #1)
15. List accessibility contact information on the home page or contact page. (CA DOR #4)
16. Include any special instructions within field labels. (Sec 508(n), IOUCA 10c)
17. As part of developer testing, run JAWS on the screen.

Specific Guidelines
18. Add a “Skip to Main Content” link in master pages. It is a Hyperlink control with a ToolTip (but no text so that it is not visible) and is the first item on the page.
    <asp:HyperLink ID="skipLink" runat="server" ToolTip="Skip to main content"  NavigateUrl=""></asp:HyperLink>
    this.skipLink.NavigateUrl = string.Concat(this.Page.AppRelativeVirtualPath, "#MainContent");
19. The first or main fieldset gets ID="MainContent" for the Skip to Main Content link.
20. Error and Success/Info messages:
    a. All error and success messages should be placed between the MainContent fieldset tag and its legend tag. This causes them to display above the fieldset visually, but when the focus is set to the fieldset, the first thing that gets read by JAWS is the message.
    b. Use labels for messages, not bulleted lists. 
    c. Use ValidationSummary controls with DisplayMode=”BulletList” for errors. HeaderText=”The following errors have occurred:”. 
    d. An asterisk (“*”) should display alongside the offending control, if possible. Error messages should not display alongside the offending control. In grid columns, leave enough room for the * to display next to the control without wrapping.
    e. Call the FocusOnMainContent() BasePage method after every message that displays in a Label.
    private void FocusOnMainContent()
        System.Web.UI.HtmlControls.HtmlGenericControl htmlBody = this.Master.FindControl("body") as System.Web.UI.HtmlControls.HtmlGenericControl;
        htmlBody.Attributes.Add("onload", "window.location='#MainContent'");
    f. Call the BasePage method AccessibleError(IValidator, string) for every error message that displays in the ValidationSummary. In the IValidator parameter, pass the validation control that you would like to invalidate. If the error is specific to a particular field, specify an associated validator in order to make an asterisk (“*”) appear next to that field (assuming the validator’s text is set to “*”). If the error does not apply to a particular field, use a CustomValidator for the whole page.
    this.AccessibleError(this.cvValidator, ErrorHelper.GetErrorMessage(100129));
    <asp:CustomValidator ID="cvValidator" runat="server" Display="none" />
    g. Similar to above for client-side error handling, for controls that invoke client-side error handling, add OnClientClick="validateAll();" Here is the validateAll() method (from the master page):
    <script type="text/javascript">
    /* After validation, reposition page to its main content. Primarily for screen readers. */
    function validateAll()
        var valid = true;
                valid = false;
    h. Consolidate all messages of the same type (error, success) into the same control. If client-side validation is occurring, this means invalidating a client-side validator on the server for all errors.
    i. Encompass the message label and ValidationSummary in a <p> to make them more noticeable. This will cause an HTML validation error due to nesting a <div> within the <p>, but it still renders and reads correctly.
21. Use divs for layout, but if there is a data table, do not mock it up using divs. Use an actual HTML <table> with <th>, <tr> and <td> tags as appropriate.
22. For search screens, at least two levels of searches should be provided: Basic and Advanced. (WCAG 13.7)

Specific Controls
23. Add the UseAccessibleHeaders property to all Gridviews. Specify the AccessibleHeaderText on the TemplateFields for more descriptive column names where needed. For checkboxes in grid cells, make the AccessibleHeaderText, for example, “Active Checkbox”.
24. Add a summary for each gridview programmatically in Page_Load:
    this.gvMyGridView.Attributes.Add("summary", "summary text"); (Use lowercase “summary” to avoid an HTML validation error.)
    b. In addition to a brief description of the gridview, include all column names and what kind of data are in them, a note about the edit/save and delete/cancel imagebuttons (where applicable). Also explain any peculiarities with the grid, such as nested grids or abbreviations in header text, to help a non-visual user to understand it.
    c. The newlines (“\n”) in the text below facilitates line-by-line text scanning by JAWS users.
    d. For grids where column headers are links that allow the grid to be sorted, add a note in the grid summary indicating this. For example, “The column header text is a link that sorts the table on this column.”
    e. For dropdown lists, in the summary, refer to them as combo boxes, because this is how JAWS refers to them.
25. For Label controls, use the AssociatedControlID property where applicable. If an ASP Label is not required but the text is associated with another control, use an HTML label tag and its “for” attribute.
26. Consider making link text understandable out of context. JAWS allows the user to bring up a list of all links to facilitate navigation, but in that list, the links are totally out of context. If the link just says something like “Edit”, it is not apparent to the user what the link does.
27. Dropdown lists: If the text fits, put “Select Level” (or whatever the field name is). Otherwise, put just “Select”. If editing a grid row with a dropdown, the text that displays should be the previously selected value. If the dropdown is then optional, it should have “Select” or “Select fieldname” selection. If it is not optional, no empty selection should be available. In some cases, instead of “Select Level” the dropdown may take the place of a corresponding label, such as Time: “Select Hour”  “Select Minute”. If there’s not enough space for “Select fieldname”, just the fieldname can be used.
28. Buttons should have AccessKeys added. For now, the button text will not have the letter underlined (this would require using an HTML button tag). Not used for imagebuttons in grids.
29. Telerik dropdown checkbox lists should not be used. Use a checkbox list or listbox instead. Avoid checkbox lists when the number of selections may exceed 5.
30. Lookup controls should have Tooltips added programmatically (cannot be done in aspx). This should already be done in the lookup user controls themselves. Also note that Lookup controls will not scale.
31. Images and imagebuttons do not need both a ToolTip and an AlternateText. Prefer ToolTips for added usability.
32. On RadDatePicker controls, add Date-Input-Font-Size=”1em” for proper scaling.
33. ValidationSummary controls should be set to Display=”BulletList” and HeaderText=”The following errors have occurred:”. They should be within a <p> along with the label control that is used for messages, and be placed in the code between the first/relevant fieldset and its legend. Visually it will display above the fieldset, but JAWS will read it first when focus is redirected to the fieldset.
34. For Validators, the Text should be “*” and come after the control it validates with no line break (or wrap). Ensure that enough room is left within columns for not only the control but the “*” from the associated validator(s).
35. Until more research is done on RadWindows, do not use them. Possible alternatives include: same page, new panel; separate page with link back to original page; new, modal browser window; perhaps the new Telerik will allow us to jump to the RadWindow consistently.
36. Do not use nested grids. Possible alternatives include putting the child grid in a new panel beneath the parent grid, “collapsing” the parent grid to only show the selected row (similar to Mall Sites, Units, Classrooms).

37. Although accessibility guidelines state that the application must be usable without Javascript, because we have a somewhat controlled user population, we are enforcing that our users must have Javascript. There is no need to code for users who do not have Javascript enabled.

38. Re-do the CSS for the entire site to unify and standardize it. Currently every module has its own CSS. This will also facilitate CSS being used more frequently.
39. Consider a fluid layout where the width of the application scales to the browser width.
40. Consider adding visible text that describes that certain fields are required, etc. Try not to let the user get an error as a way of figuring out how to use the screen.
41. Eliminate reliance on device-dependent Javascript. Certain Javascript events such as mouseover assume the user is using a mouse. Use onclick instead, where the user can use either a mouse or a keyboard (or other assistive technology).
42. Provide a site map for the site. (WCAG 13.3)
43. The menu system should be changed so that it is consistent throughout the application. The menu items that change depending on the current module should be moved to a sub-menu system. Also consider providing pages that can be navigated to for every link on the menu. (WCAG 13.4)
44. Some minor re-working should be done to standardize the UI for all pages. (WCAG 14.3)
45. Eliminate in-grid editing. Place only unique identifier in the grid, then open an edit panel with all of the data items in a vertical layout.

Posted on Thursday, May 29, 2008 10:37 AM | Back to top

Copyright © Mike Ellis | Powered by: