Armagan Tekdoner Web Accessibility Specialist
WCAG fascinates me, mostly because there is nothing self-explanatory there
As a web accessibility analyst, I discuss the criteria that cannot be reliably tested by automated tools and common misconceptions in this page, by providing clear examples of false positives.
Comprehensive updates are on the way.
Here is a document providing easy tips for avoiding many accessibility errors during development: Developer-friendly WCAG checklist
What are decorative images and how to correctly code a decorative image?
Non-text Content — Level A Failure of Success Criterion 1.1.1 due to providing a text alternative that is not null (e.g., alt="spacer" or alt="image") for images that should be ignored by assistive technology
1.1.1 covers a wide range of topics. A tricky one is handling the images that are decorative. There are tonnes of information readily available and I would like to share my own take in case someone might find them useful.
I describe a decorative image as an image the user can do without. In other words, remove the image and see whether there is any information missing. Decorative images are sometimes obvious, such as a paragraph spacer. However, sometimes they look like normal images that need alt
attributes to describe them. Generally, such images take the form of photographs, used from stock photography agencies, not giving a clue about the actual matter.
"A picture is worth a thousand words", as the saying may go. Here are example cases in which the picture is not worth even a single word and it can safely be ignored by the assistive technology. (The demo itself as a whole, may worth a thousand words though.)
Decorative images
This is the first paragraph about something.
And this is the second paragraph separated from the first one by the image above.
Decorative. No alternative text. This is an image you can immediately understand you can do without.
This is a paragraph explaining the arrival procedures in detail, at Toronto airport, preceded by the image above.
Decorative. No alternative text. This is an image you can easily understand you can do without.
This is a paragraph explaining the arrival procedures in detail, at Toronto airport, preceded by the photo above.
Decorative. No alternative text. This is a photo that looks like relevant at first glance but it adds no value to the text or provides no information whatsoever.
Incorrect alt
attributes commonly used for decorative images
<img src="paragraph-spacer.jpg" alt="null" />
<img src="paragraph-spacer.jpg" alt="NULL" />
<img src="paragraph-spacer.jpg" alt="decorative" />
<img src="paragraph-spacer.jpg" alt="decorative paragraph spacer" />
<img src="paragraph-spacer.jpg" alt="spacer" />
<img src="paragraph-spacer.jpg" alt=" " />
<img src="paragraph-spacer.jpg" />
One and only correct alt
attribute for decorative images
<img src="paragraph-spacer.jpg" alt="" />
For the "Meaningful Sequence" criterion to apply, the content sequence must affect the meaning in the first place
Meaningful Sequence — Level A Understanding Success Criterion 1.3.2
When it makes no difference when some content is presented first and some other second, this does not apply.From WCAG
This describes the failure condition that results when CSS, rather than structural markup, is used to modify the visual layout of the content, and the modified layout changes the meaning of the content.
Imagine 3 articles on one page, about "Birds", "Dogs" and "Cats" subsequently.
When CSS is disabled, the reading order becomes "Dogs", "Cats", and "Birds". The actual DOM structure is what you see after disabling the CSS and the styling was distorting the order; but there is no 1.3.2 failure here, as there is no change in the meaning of anything.
Show me that page described above with a button that disables the styles and I will understand why the page WILL NOT fail 1.3.2 even when the sequence changes due to disabled styles
Consider again the same page about the 3 animals.
When CSS is disabled, the captions under the animal pictures are incorrectly assigned. The actual DOM structure is what you see after disabling the CSS and the correct order you saw was assigned by styling; there is a 1.3.2 failure here, as the meaning changed.
Show me that page described above with a button that disables the styles and I will understand why the page DOES FAIL 1.3.2 when the sequence changes due to disabled styles
How to create a basic, CSS-only "Skip to Main Content" link?
Bypass Blocks — Level A Understanding Success Criterion 2.4.1
Keyboard-only users have to use the tab key to navigate. They must tab through a lot of links just to get to the main content. A skip to main content link allows them to bypass blocks such as menus.
Show the "Skip to Main Content" link example
Show the "Skip to Main Content" link on jsfiddle
What a page title is, where it is located, what it is for, and most importantly, how it should be authored
Page Titled — Level A Understanding Success Criterion 2.4.2
I assume almost all web practitioners know whats and wheres part of the above heading, I am simply refreshing minds first
It is the title
element residing in the head section of the HTML document.
What is it for?
- When many tabs are open, it right away reminds a user which page belonged to what website
- In a lengthy bookmarks list, thanks to properly-authored titles, a user can immediately understand what page a shortcut belongs to without the need for opening it
- Search engines display what you write as titles in their results (Try limiting them to 55-60 characters)
Rules:
- It must be located in the
head
block - Make sure to correctly open and close it:
<title>text text text</title>
- It can contain nothing but text, no markup inside it is allowed
- All pages must have their own unique titles
- Leaving it empty is not an option
- One screen cannot have more than one title
- No aria role permitted
What I want to talk about is the "how it should be" part of the heading
The ideal title text must at least provide 2 details:
- Which website it belongs to
- Which screen/process/page it is about
More failure examples in addition to the clear ones shown in 2.4.2 failures page:
<title>Home page</title>
— fails 2.4.2 as it is not telling the user which website it belongs to<title>Contact us</title>
— fails 2.4.2 as it is not telling the user which website it belongs to<title>BBC</title>
— fails 2.4.2 as it is too broad, not telling the user what the page is about<title>NEWS</title>
— fails 2.4.2 as it is not telling the user which website it belongs to<title>BBC NEWS</title>
— still fails 2.4.2 if it is an article, as it is not telling the user which article it is<title>The training that helps your dog lead a better life</title>
— also fails 2.4.2 as it is not telling the user where that article is from<title>very year at Crufts, the UK's largest dog show, canines and their people can participate in all manner of exciting competitions. Whether heelwork-to-music (essentially dancing with dogs) or obedience, or the high-speed relay races of flyball, it can be a marvellous feast of fun for performance dogs.</title>
— fails 2.4.2: just too long<title>future,ARTICLE,story,domestic-animal</title>
— fails 2.4.2 as it is the list of keywords, not a title<title>The training that helps your dog lead a better life - BBC Future</title>
— PASSES 2.4.2, which is the original title
The article used for the examples is Dogs, like humans, need to learn basic "life skills" By Jacqueline Boyd, retrieved on 14th April 2022
This is how I authored it for this page:
<title>WCAG - A Web Coding Showcase | Armagan TEKDONER</title>
The tabindex
global attribute
Focus Order — Level A Understanding Success Criterion 2.4.3
One of the 2 failures specified by WCAG is Failure of Success Criterion 2.4.3 due to using tabindex to create a tab order that does not preserve meaning and operability
The meaning and the operability are explained in detail in the official resources. Here, I want to address the frequently-misunderstood tabindex
usage.
- Rule number 1 is that the
tabindex
attribute is not normally needed: properly coded HTML5 takes care of the focus order matter - There are only 2 reasons why it can be used and there are only 2 correct values it can take
-
Reason: Some natively not tabbable element needs to be inserted into the tab order, such as a scripted
div
that works as a link, but does not receive keyboard focus
Correct value: 0 -
Reason: Some natively tabbable element needs to be removed from the tab order, such as a hidden element that receives focus by default
Correct value: -1
-
Reason: Some natively not tabbable element needs to be inserted into the tab order, such as a scripted
- No values apart from 0 and -1 should be used and anything higher than 0 alters the tab order.
Using positive values is allowed (the maximum value fortabindex
is 32767), but it is a very bad practice. And please let me state the obvious: using anything lower than -1 (the minimum value fortabindex
is -32768) will not better remove an already removed element 😀
The tab order is set by the tabindex
attribute as follows:
tabindex='1'
(The highest priority)tabindex='2'
(The second highest priority. 3,4,5 ... 32767 — in that order)tabindex='32767'
(The lowest priority)tabindex='0'
(The natural order, default value, when no priority is assigned)tabindex='-1'
(Not in tab order)tabindex='-32768'
(Not in tab order)
Here is a tabindex
demo
Click here and start tabbing to see for yourself.
A common false positive: link purpose should not be used to fail broken links
Link Purpose (In Context) — Level A Understanding Success Criterion 2.4.4
"Learn more", "read more" or "click here" type of text links, are not automatic failures either. It is all about understanding the purpose of the link without needing additional context: not a quality control mechanism nor a sort of keyword hunting.
2 common incorrectly-reported failures:
- See an example site. (Link is broken. This is not an accessibility problem that excludes only a group of people, everyone is equally impacted. Broken links are not included under any of WCAG criteria.)
- Learn more about what is not considered a 2.4.4 error. (How can anyone not understand what is to be learnt more here?)
Focus outline shows which element has the keybaord focus
Focus Visible — Level AA Understanding Success Criterion 2.4.7
The keyboard focus is where it all begins. Go to any website and start tabbing. Do you see the elements that receive focus? Try this website too.
It only takes one simple line of CSS code, as exemplified below. Please make sure that there is no background colour matching the outline colour you chose!
:focus{
outline: 2px solid #bb0000;
}
Not all parsing errors are WCAG errors. The section below is for WCAG 2.1.
Parsing — Level A Understanding Success Criterion 4.1.1
4.1.1 specifies exactly which type of parsing errors are considered failures; therefore, apart from the specified, no other error should be reported.
Of course "Fully conforming to specifications", as G192 sufficient technique says, does guarantee that the web page passes 4.1.1, but this is more than "sufficient". In fact, the first 3 sufficient techniques are too sufficient. Since any fool can run an HTML validator to see whether it reads "Document checking completed. No errors or warnings to show," there would be no need for WCAG testers. Just don't expect today's Power Apps, on which many of the websites based, to generate fully conforming codes. (Check the web giants' websites and see how many parsing errors they have. There is no such website as "fully conformant".)
The true WCAG errors are listed and explained below.
- "Elements have complete start and end tags, attribute markup has been correctly authored." In other words, missing any or all of these 3 <, /, > or errors in usages of = and " or '. WCAG F70 failure testing procedure says "Check whether any opening tags, closing tags or attributes are malformed". "What exactly and how?" you say?
<span>Dummy text<span>
(Forward slash has been forgotten in the closing tag.)<strong>Dummy text<p>
(No closing tag in sight; a new paragraph begins.)<divDummy text</div>
(Opening tag misses this → >)<label for="name class=myLabel">Name:</label>
(The closing and opening quotes of the values missed.)<label for="name"class="myLabel">Name:</label>
(There should be white space between attributes, boundary becomes unclear.)<label for=family name>Family name:</label>
(Attribute value with a white space and without quotes confuses the parser, makes it think name is an attribute.)<label for="family name">Family name:</label>
(Attribute value with a white space gives a "bad value" error.)<label for"name">Name:</label>
(= sign forgotten, causing 2 errors about unmatching quotes and one attribute error.)<label for="name'>Name:</label>
(The single quote after the value "name" that was intended to close the quotation, makes the parser think the closing of the attribute is yet to come.)
- "Elements are nested according to their specifications." How does incorrect nesting look like?
Example 1
<span><strong>Dummy text</span></strong>
(The closing tag for the strong element comes after that of its parent element.)Example 2
<ul>
<li>Dummy list item 1</li>
<li>Dummy list item 2</li>← Oops! The list item should not have been closed here...
<ul>
<li>Dummy nested list item 1</li>
<li>Dummy nested list item 2</li>
</ul>
</li> ← ...the closing of the list item should have been here instead.
</ul> - "Elements do not contain duplicate attributes." WCAG H94 sufficient technique testing procedure says "Check that no attribute occurs more than once on any element".
The following are 4.1.1 error examples.
-
<p
(Don't do this.)class="class1" class="class2">Dummy text</p>
<p class="class1 class2">Dummy text</p>
(Do this instead.) -
<img
(Don't do this.)src="the-photo.jpg" src="the-photo.jpg"alt="" />
<img src="the-photo.jpg" alt="" />
(Do this instead.)
-
- "IDs are unique." WCAG F77 failure testing procedure says "Check that all values of type ID are unique in the Web page".
The following are 4.1.1 error examples.Example 1
<p id="name">Enter Your name:</p>
<input id="name" />
Example 2
Question: What is wrong with this table?Animals Plants Cats Flowers Dogs Vegetables
Answer: Its IDs and headers. Reading its code below, the screen reader will say cats, dogs, flowers and vegetables are all both plants and animals. Whereas, all that the validator says is "Duplicate ID".
<table>
<tr>
<th id="ID1">Animals</th>
<th id="ID1">Plants</th>
</tr>
<tr>
<td headers="ID1">Cats</td>
<td headers="ID1">Flowers</td>
</tr>
<tr>
<td headers="ID1">Dogs</td>
<td headers="ID1">Vegetables</td>
</tr>
</table>