Efficient Web Accessibility Testing — AChecker


Version tested: Unversioned web service (as of December 2014)

Mode of operation

While AChecker can be downloaded and installed locally as a PHP package, it is most commonly known as a web service, where it can be used in three modes:

The service uses a web crawler to fetch the document for processing, hailing from courseware.idrc.ocad.ca, with an empty user agent and referrer field. There is no way to override this, and due to the fact that such bots are universally banned by system administrators due to widespread abuse, this bot might have to be temporarily white-listed before any checks can be performed. If it is not white-listed, it will proceed to validate the server-generated 403 status page instead of informing the developer that the request was denied by the server. If it is explicitly white-listed, it will not download external resources such as images itself (but stylesheets and scripts), instead of using the browser to do so, and then displaying the images in its reports.

Error reporting

Testing results are presented on the same page as the form control of the service. Reports are split into five categories:

Due to the use of the jQuery JavaScript library, switching between the aforementioned report groups is not possible if scripting is turned off. There is no explanation provided as to how issues found on validated pages are divided into categories. The first two seem only to differ in severity, while the third category, potential problems, is a list of issues to be checked manually, generated based on the presence of certain elements, attributes, or resources, with no analysis performed. Instead, a host of accessibility guidelines which may or may not refer to the object in question is presented for inspection. Only the flagged issues from the first two categories are of interest to the users of this service, and several examples of the third category will be used to describe its lack of usefulness.

Even though the source code of the validated page is not displayed in relevant fragments with inline injection of marks, only the offending tag (at the maximum a three-line portion of its contents) is listed, along with its line number in the source code, but no immediate surroundings are provided for context, so having the source of the given document open in an editor is necessary.

It is worth noting that advertisements are served on the service page.


The AChecker does not perform CSS or HTML validation, instead outsourcing the task to the respective W3C validators. However, these options (not selected by default) do not work. The service seems to have been abandoned since 2011, the latest timestamp to be found on the site. Any attempt to use these options will result in one of the following errors:

CSS validator error. Unable to generate results from the validator.

Cannot find result report from the return of the validator.

The list of accessibility guideline releases to choose from includes:


The outsourced validator services are broken, and AChecker does not perform any checks on its own. It also ignores external or inline stylesheets as well as external or inline vector graphics.

HTTP: Server headers — language

The most prodigious source of false positives in AChecker is due to its failure to check and process server headers, which is the most efficient way to declare encoding, language, content type, navigation structure of auxiliary documents, and even stylesheets. Here is an example of the Apache server configuration:

AddLanguage no .html

This can be overridden anywhere down in the URL hierarchy, or from the top configuration file, for example through the <Files> directive. Server headers are trivially checked from within the graphical browser, see the examples from Firefox/Pentadactyl:

server response, Norwegian version server response, English version
Server responses in a graphical browser

The same information can be trivially obtained from the command line, using a text browser:

% lynx -head -dump //unicus.no/ | grep Language
Content-Language: no
% lynx -head -dump //unicus.no/en/ | grep Language
Content-Language: en

AChecker does not check and process server headers, and thus will complain that the language is not set for the document, with the following error:

3.1 Readable: Make text content readable and understandable.

Success Criteria 3.1.1 Language of Page (A)

Check 48: Document language not identified.

Repair: For HTML documents add the lang attribute and a valid ISO-639-1 two letter language code to the opening HTML element. For XHTML documents add both the 'lang' and 'xml:lang' attributes with a valid ISO-639-1 two letter language code to the opening HTML element.

Check 49: Document has invalid language code.

Repair: Add a valid 2 letter or 3 letter language code as defined in the ISO 639 specification to the HTML 'lang' attribute. For XHTML, both 'lang' and 'xml:lang' must be set.

Using the lang attribute is the only way to avoid the false positive (note that xml:lang should not be used in HTML pages). This attribute makes sense for standalone documents (such as testcases), and even then only for those which are shared through other means. Recommending this attribute is poor advice even for small servers, let alone huge sites with thousands of pages. Documents servers with a valid server header should never fail validation.

Failure to check and parse server headers is a critical flaw in automated accessibility checkers. Here are some facts:

AChecker does not check, parse, or process server headers, but at least it doesn't issue bogus content type error warnings for other server headers, such as Content-Script-Type and Content-Style-Type. It is also worth noting that AChecker for a set of pages/sites with correctly configured servers appears to be random — some pages will trigger the error, some will not, with no discernible cause. In that, AChecker reporting is not predictable, not even in the case of false positives.

HTTP: Server headers — links

Stylesheets can be added to documents via link elements, but links need not reside within the documents themselves — they can be set on the server. An example of this is the following Apache server configuration:

<Files ~ "index\.(html)$">
Header add Link '</css/define.css>; rel="stylesheet"'

This directive injects a stylesheet link to all documents with the html extension. It may be used as a global stylesheet for the entire site, as a base stylesheet to be overridden by document-specific stylesheets, or as a way to neatly define CSS Variables, on its own a useful accessibility feature of cascading stylesheets. It is unfortunately not mentioned in the WCAG 2.0 standard, which it post-dates.

AChecker is be unaware of such links. The same applies to color contrast errors which may be present in such stylesheets.

Check 306: The contrast between the color of text and its background is not sufficient to meet WCAG 2.0 Level AAA.

Non-sensical or otherwise erroneous headers sent by misconfigured server will also not be caught. A particularly egregious example of a document on a misconfigured server looks like this:

Content-Style-Type: ape/monkey
Content-Script-Type: monkey/ape
Content-Length: 209
Connection: close
Content-Type: gorilla/orangutan; charset=utf-8
Content-Language: gorilla

Unlike web browsers which do check for HTTP headers and will treat documents with associated nonsense headers as downloadables of unknown type, AChecker will download and parse the document, and then report that it is perfectly valid and accessible.

HTTP: Server headers — site navigation links

Other link types can also be specified on the server, such as the site map, copyright notice, newsfeed, and many more:

<Files ~ "index\.(html)$">
Header add Link '</index/>; rel=index'
Header add Link '</legal/>; rel=copyright'
Header add Link '</atom.xml>; rel=alternate; type=application/atom+xml;
	title="site updates newsfeed"'

These links affect accessibility in more ways than one. Some applications populate a separate navigation bar with these links, where they may appear as text and/or icon buttons. Others may add it to the text menu. Some more advanced search engine robots process server headers and may present information extracted thus in the site overview. It is also recommended that newsfeeds are appended to the documents through such a link.

AChecker is be unaware of such links. Non-sensical or otherwise erroneous headers sent by misconfigured server will also not be caught. Documents linking to newsfeeds within the body of the document, but neither through a head link nor a server header link, are not flagged.

Pre-formatted text

AChecker does not understand the semantics of the pre element, not even if its inline contents are marked up as sample computer output (the samp element), or code (the code element). Instead, it flags the document as erroneous, issuing the following error messages:

Success Criteria 2.4.1 Bypass Blocks (A)

Check 84: ASCII art possibly missing a skip-over link.

Success Criteria 1.3.1 Info and Relationships (A)

Check 154: pre element may be misused to create tabular layout. Manual Check Required.

The first error will flag all pre elements as containing ASCII art. The second error instead is an example of potential problems reporting described in the introduction. Developer time is better spent on processing reports from smarter tools.

Multiple caption elements

AChecker does not flag multiple caption elements as erroneous.

<caption>sufficient description here</caption>
<caption>invalid caption element</caption>

Instead, its potential problems checker will recommend that a summary attribute be added. For other tables, it will recommend that a data table may require a caption, or that the caption element be removed. Since it does not have the ability to distinguish whether the table is used for data or for layout, what it reports is pretty much random.

Images and objects

AChecker will issue a host of false positive errors for any object elements it encounters, including image objects. While some objects with parameters may be used as plugin containers, this element is a generic element, which can also be used for inline text frames, and in particular, image objects:

<object data="/path/to/image">
	...object fallback...

The type attribute is redundant as long as the relevant Content-Type header is set, and in the case of common images, it always is. The difference is only in browser processing speed. Regardless, AChecker will always flag objects. Some error examples:

Check 251: Image may contain text with poor contrast.

Check 73: object may be using color alone.

Check 253: This image may contain text with poor contrast.

Check 259: object may not provide a keyboard mechanism to return focus to the parent window.

Check 30: object may flicker.

In other words, every object is suspect, as is every img image, generating a massive number of false positives. See also the next section.

Links and headers

As a final example of non-sensical reporting within the potential problems category, consider the following example, generated for every link and heading on the page:

Check 19: Link text may not be meaningful.

Check 42: h1 may be used for formatting.

Check 43: h1 may be used for formatting.

Since everything is flagged as potentially erroneous regardless of actual content, inspection of such error results is a tremendous waste of time. It is recommended that potential users of this service limit their usage of it to the first two categories, known problems and perhaps likely problems.


Major issues with AChecker:

There are no benefits of using AChecker because of its limited scope, poor usability, and a massive number of false positives. It does not have any advantages over other tools, while its analysis is inferior to that of competing tools.