My Web Accessibility Checklist
Website Accessibility is a big subject, and the W3C's Accessibility standards include a huge number of principles and techniques that must be implemented if a website is to be fully accessible to the the largest possible number of visitors, including people with various disabilities. There is an even greater number of articles on the subject available on the Internet, all explaining in detail the reasons for various techniques, and who they help.
But what I need in my day to day work is simply a check list of the many tasks to be done for Accessibility, so I don't forget anything in whatever page I am currently working on. No explanations required and general broad principles not wanted - most Accessibility developers know the principles and the reasons why. I just want something I can simply run my eye down quickly to make sure I've done it all and not forgotten anything.
I also want something I can use as a crib sheet if I'm tasked with converting an existing website to Accessible form.
I don't know of any such list previously created by anyone (though no doubt there are some lists around that I have missed). So here is a simple reminder checklist of many of the things to be done as routine, compiled from W3C's Web Content Accessibility Guidelines (WCAG) 2.0.
This list covers most of the recommendations (the techniques) embodied in W3C's list of "Techniques" for satisfying their WCAG 2.0 up to and including AAA level. And now you see why I have not discussed the underlying principles. The list of things to implement is quite long enough for a single article without including all the explanations!
In creating this list I have looked at each of W3C's "techniques" - the methods they recommend to implement particular requirements. However not all these techniques are useful. For instance, to ensure a good contrast between foreground and background colours, W3C's technique G148 suggests not setting colours at all on a website, but simply showing everything in the default (i.e. black and white) set by the browser. That isn't going to happen; 99% of websites use colour; designers design them that way because it looks far better to the majority of people. So this technique, while technically workable, is not sensible, and I haven't recommended it therefore. Likewise G156 was useful once, but today most main browsers cover it themselves. Several suggested techniques come from the very earliest days of the Internet, and have little relevance today.
So, where W3C allow a choice of techniques to achieve a particular requirement, I have chosen those that make most sense in the average website. There are often several alternative ways of achieving something, but not all such methods are popular. So I have chosen the ones that are generally accepted as the way to go. My intention is to provide guidelines that, if followed, will result in a WCAG compliant website. However, if you choose to achieve something in an alternative way, by all means do so, so long as it satisfies the relevant accessibility requirement. For instance, an alt tag can be left empty (but not missing) on an image if the text has already said, "The following photograph shows a broken exhaust support on a Rover 600". Indeed, repeating those same words in an alt tag would actually be tiresome for a screen reader user who would then have to listen to them twice over!
Note that AT means assistive technology (including screen readers, Braille readers, and so on).
So here is my check list, divided into sections according to the HTML elements they relate to (but please note it is still work in progress):-
In the <head> section:
- check the <html> element contains a valid lang attribute
- check the <title> element is present, not empty, properly describes the page, and is unique
- check any meta viewport element does not contain maximum-scale=1 or user-scalable=0
In the source code:
- check headings on page are all done with h1 - h6, in correct order
- check h1 - h6 are only used for genuine headings
- check logo and common page headers do not use h1 to h6
- check all menus use the <ul> list element
- check any breadcrumbs list has a text description for AT
- check any layout tables have role="presentation"
- check all radios and checkboxes have frameset and legend (unless very simple sets)
- place a "Skip to main content" link at the top of every page, going to the first main content not a sidebar
- if tabindex is used check no preceding links or fields are missing their tab index
- if tabindex is used ensure the "skip to main content" link has a tab index higher than anything else
- place other "Skip" links to skip other long sequences of repetitive navigation
- check all links, buttons, and input fields stand out well on keyboard focus, not just using the browser defaults
- check you can Tab onto every interactive item, with no traps
- where several tab-indexed links or form fields should be entered in the order they appear in the HTML, give them the same tab index
- check form fields have tabindexes if they should logically be processed in an order contrary to their sequence in the HTML markup
- check any onClick event (on anything other than a link or button) has a matching onkeypress handler
- check any onmouseover event has a matching onfocus event
- check any onmouseout event has a matching onblur event
- check all links, buttons, and input fields stand out well on hover using structural indicators (e.g. underlining) not just colour
- identify links in the normal state using underlines (or bold, italics, or change of font) unless they are clearly links from the context
- where unvisited links are not underlined, check they have a) contrast with surrounding text by over 3 to 1, b) over 4.5 to 1 contrast with their background c) are underlined (or otherwise structurally highlighted) on both hover and keyboard focus
- check all link text indicates the link's purpose (not just "click here" etc)
- check any image links have alt text on the image explaining the purpose of the link
- where a text link and adjacent image link target the same destination, combine them into a single link, with blank image alt text
- where multiple adjacent elements need to be linked to a single destination, combine them in a single link if feasible
- warn the user if a link will open in a new window
- don't fix the page text size, leave it enlargeable (check text enlarges in IE)
- check all text, and all other page content, remains visible and uncorrupted when the page is text-zoomed in the browser up to 200%
- check no text overflows onto other text, images, or other page content, when the page is text-zoomed in the browser up to 200%
- check no text overflows its container, or becomes clipped or hidden, when the page is text-zoomed in the browser up to 200%
- check all lines of text can still be read, without scrolling the page, when text zoom of 200% is applied in the browser
- check any foreign language content is exclusively contained in a lang attribute
- ensure all text contrasts strongly with it's background (at least contrast ratio 4.5:1 for AA, for normal size text, 3:1 for 18pt+)
- check all text colour settings are accompanied by an appropriately contrasting background setting and vice versa
- ensure nothing relies on colour alone for it's meaning, or becomes unidentifiable if colour is removed (e.g. 3 coloured lines on a graph)
- check that where changes of colour, font, style, positioning, borders, etc have been used to identify or classify something, then explicit text is somehow added to convey the same information
- if text is superimposed over an image check the text and image contrast is compliant, as above, across all the text
- if text is superimposed over an image check the text and image contrast remains compliant, as above, at all text zooms up to 200%
- note: brand logos are exempt from the above requirements concerning colour, contrast, size and text-zoom, but must have suitable alt text
- check there are no font sizes in fixed units (px or pt units)
- check all line heights in blocks of text are between 150% and 200%
- check all paragraph spacing is at least 2em (advisory only)
- check text containers are variable width (by %age, rem or em units) so they change with screen width, to avoid horizontal scrolling
- check no columns of text become narrower than about 6 or 7 words per line, at all text zooms up to 200%
- check no columns of text become narrower than about 6 or 7 words per line, at all screen widths including mobiles
- check no text is justified
use of HTML elements:
- check for content that is visually laid out in the form of a list or other collection of items, and ensure they are in <ul>, <ol>, or <dl> elements
- check all menus are done using <ul> or <ol>, not by un-associated sequences of links
- check all headings are done using <h1> - <h6>, not plain text, and in correct hierarchical order
- check all h1 - h6 elements are for meaningful headings, not purely to achieve visual formatting
- check all <em> tags are for visual/sensory emphasis only, while all <strong> tags are for content that has importance to the meaning
- check text is not formatted into lists using <br> line breaks
- check text is not formatted into columns or rows using spaces, tabs, <br> etc
- check data is not formatted into tabular format using spaces and <br>, line breaks etc or other non-table elements
- check all external references are in <cite> tags and the quotations are in <blockquote> or <q> tags
- check all content that should be superscripted or subscripted is done using the <sup> and <sub> tags
- check that lists are done using <ul>, <ol>, or <dl>, not by unassociated paragraphs (but comma separated lists in a single sentence are ok)
- enclose all abbreviations and acronyms in <abbr> tags, so screen readers read the letters not the word
- for each <pre> element, check the enclosed information is not tabular
- if artificially enlarged letter spacing is used, do it using the CSS letter-spacing, not by adding spaces
- check all textual information has been added as text markup, not in the form of an image
- check every non-decorative image has a short alt attribute or an alternative text
- check the logo image(s) has alt text e.g. "Logo of .... Ltd"
- ensure every alt attribute conveys the same information as its parent image, not simply describing the scene in, or look of, the image
- check that if any image were to be removed, the alt or longdesc attributes are sufficient to convey the same information
- on purely decorative images add alt="" and no title
- on images where alt text is not required (e.g. because the information is contained in other text), add alt="" and no title
- check that purely decorative images are created in the CSS not the HTML where possible
- if an image contains words that convey information, include those words in the alt attribute
- if images of text are used as headings, add H1, H2.... tags off-screen to retain the document hierarchy for assistive technology
- if the information being conveyed by an image is too long for an alt attribute, just put a summary in the alt attribute, then create a detailed description and add it to the page, or link to it from beside the image, or add a longdesc attribute for it
- check that information conveyed by colour in images (eg coloured lines on graphs) is also conveyed in alternative text
- make images enlargeable
- check that images that convey information are not CSS (or Dom) background images, or else there is a text alternative
- on sets of associated identical or nearly identical images, only give a completed alt attribute to one image in the set, leaving the others as alt=""
- on image buttons give meaningful alt text explaining the button's function (e.g. not just "How?", but "How to get this discount?")
- check all <area> elements of image maps contain an alt attribute describing the purpose of the link
- if information is conveyed by colour without text use patterns or other structural differences to differentiate the coloured objects (e.g. in bar charts)
- check the text prompt for every form field is a <label>, not plain text
- check the displayed values of all radio buttons and check boxes are labels
- check any form fields that have no label have a title (or following button) instead to say what the field is for
- ensure all labels have a "for" attribute and it points to the correct field
- if a form field has no label, consider giving it one rather than using a title
- check any button elements with no text inside them have a title instead to say what the button is for
- check labels and their fields are close together at all screen sizes
- do not allow any placeholders within fields instead of a label
- contain sets of radio buttons or checkboxes in <fieldset> elements
- check every fieldset has a legend, even if hidden off-screen, describing the purpose of the contained fields
- if a heading or other text has been used to identify and group several form fields, use a <fieldset> and <legend> instead
- check text information about a fieldset of radio buttons, checkboxes or other fields is held in the fieldset <legend>, not as plain text
- check all fieldset legends are very brief (as screen readers read them before every field)
- indicate required fields either by adding "(required)" to their labels, or adding at the top of the form "Required fields are indicated by [e.g. asterisk or in bold (use <strong> tags for this), not by colour]
- don't use asterisks to mark mandatory fields as assistive devices vary in how they treat them
- where some options of a <select> are grouped together, ensure this is done using <optgroup>, not by dummy list items
- check all <optgroup> elements have a label attribute showing the reason for the group
- ensure all tabular data or information is presented in <table> elements
- consider whether very complex tables would be better if replaced by two or more simpler tables
- give every data table a <caption> element to explain the table for assistive technology
- check table captions are in <caption> tags, not in unassociated plain text
- check the summary attribute of data tables to ensure it is suitable for assistive technology, to summarise its purpose and/or explain the navigation of complex tables
- check each table's summary does not duplicate the caption
- use <th> for all table header cells
- where <td> data cells also function as a header, give them a scope attribute
- use the abbr attribute of <th> to abbreviate long table headings to give screen readers a short heading before each cell
- use the headers attribute and ids in complex tables to associate data cells with their header cells
- if layout tables are used (not recommended) do not give them a caption, summary or scope attributes or use <th> headings
- if layout tables are used check the content still makes sense when read horizontally across the screen one row at a time
- check any custom controls pass their role, purpose, and states, properties and values to AT
- applets - check they have an alt attribute summarising what the applet does
- <object> elements - check they have alternative text with same information, placed between their opening & closing tags
- <embed> elements - check they have alternative text with same information, placed between their opening & closing tags
- ASCII art, emoticons or leetspeak - check these all have a text alternative if information is conveyed, and are hidden by aria-hidden="true"
- ASCII art - check they have a "Skip ASCII image" button as well, and/or hide it with aria-hidden="true"
- check rows of asterisks are done by :after or have aria-hidden="true"
- for captchas provide also an alternative task that can be completed by anyone
- check any captcha has text instructions saying what input action is required, and mentioning the alternative facility
Custom and re-purposed elements:
- check all interactive custom controls can be reached by the Tab key, and in logical sequence
- check all custom controls have an ARIA role
- check all re-purposed HTML elements have an ARIA role
- check custom link components have role="link"
- check all custom controls have an aria-labelledto, or other instructions to tell AT users what the field is for
- check all re-purposed HTML elements have an aria-labelledto, or other instructions to tell AT users what the field is for
- check the initial states of any custom controls are passed to AT
- check any runtime changes to the state of any custom controls are passed to AT
- check the initial properties of any custom controls are passed to AT
- check any runtime changes to the properties of any custom controls are passed to AT
- check the initial value of any custom controls are passed to AT
- check any runtime changes to the value of any custom controls are passed to AT
- use a validator to check for invalid HTML markup
- check horizontal scroll bars do not appear at any size of text zoom up to 200%
- check horizontal scroll bars do not appear at any screen size
- check that content positioned using CSS positioning (absolute, fixed or relative), floats, or tables is in the same order in the HTML source as visually on-screen,
- check that content positioned using CSS positioning (absolute, fixed or relative), floats, or tables will maintain its meaning and order if the stylesheets are removed
- check that links and input fields appear in the same order in the source as they are in the default tab order
- check :before and :after don't contain content needed for the meaning, or else repeat that content another way
- check every non-textual element has an alt attribute or an alternative text
- check value ranges use the word "to" rather than a dash (e.g. age 20 to 30 not ag 20 - 30)
- ensure all link text is concise (but still meaningful), not using entire blocks of text as links
- check link lists that are merely a series of numbers or letters have prior text to say what the links are for (e.g. "Go to search results page 1 2 3 4..."
- do not convey information solely by colour
- do not convey information solely by the position, shape or size of objects, as these are meaningless to screen readers; include text
- check all element ids are unique within the page
- check all accesskey attributes are unique within the page
When making amendments
- check that updates to one element are reflected in changes to any associated elements
- ensure alt text is updated if necessary when its parent image or non-text element changes
- when adding new links, buttons or form fields check if surrounding elements have a tabindex, and set tabindex on the new element if necessary
- as a Final Test (or even an initial test up front), check items on screen retain their correct meaning and sequence on screen when CSS stylesheets are removed
Some of the above you will probably never use. For instance who does Ascii artwork these days....but you might be asked to convert an old site that has some in it, and imagine the hassle it causes when a screen reader user suddenly inundated with a large ascii artwork being spelt out letter by letter! So we need to know about these things. However I have placed some of the more esoteric things, like that, at the end of their section to keep them out the way a bit.
So apply accessibility principles as you code, but once you have finished run it past the list above to check it's all there.
Some Added Points
Remember that many of these techniques are not always necessary for conformance to WCAG, provided some other method is used to provide the same accessibility. For instance, an image could have a blank alt attribute (but not no alt attribute at all, for the sake of screen reader users) if the important features of the picture are all described in detail in the text, as in, "The following diagram shows how.....". Indeed, a user of assistive technology wouldn't want to have to listen to the same words twice over, in the text content and again in an alt tag!
It is also a fact that a page can be totally accessible on first creation, but later amendments or additions to it may forget things. For instance, a new field might be added into a set of fields, but the developer might easily not notice the existing fields are tab-indexed, and so not add a tab index to his new field, thus effectively making the field invisible to screen reader users until long after the end of the form. (Even worse if it is a compulsory field, and the user can't tell where it is!) So if we have a site that is often updated, perhaps by multiple developers, it might be worth running this list by it every year or two.
One point worth noting is that the use of the title attribute on HTML elements is pretty pointless these days. Not that they were very accessible at any time, being in too small a font for many people to read, and usually disappearing after a few seconds before people could finish reading the longer ones. But mobiles and touch screens and many other devices, including most assistive technology, do not support titles at all. Never, never put needed information into titles! If you need to add more information because something isn't sufficiently clear, then it should go into the main text, so everyone can see it.
Web developers and designers who practice accessibility might decide to keep a copy of this list beside them (I will be honoured if they do!). It is not an exhaustive list, but it should cover most of the everyday matters that need to be covered on every web site. If you think I have left out something important, with the exception of the matters I said at the start were omitted, please let me know.
It is important for us not to inadvertently forget anything needed by disabled visitors to our websites and I hope you will find this list a useful tool for that.