Skip to content

Commit 623d26e

Browse files
Rule visible-label-in-accessible-name-2ee8b8: introducing a new "label in name
algorithm". It's intended mostly to handle whitespace and punctuation.
1 parent 8a5d415 commit 623d26e

5 files changed

Lines changed: 299 additions & 17 deletions

File tree

_rules/visible-label-in-accessible-name-2ee8b8.md

Lines changed: 220 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ acknowledgments:
2323
authors:
2424
- Anne Thyme Nørregaard
2525
- Bryn Anderson
26+
- Dan Tripp
2627
- Jey Nandakumar
2728
funding:
2829
- WAI-Tools
@@ -38,10 +39,14 @@ This rule applies to any element for which all the following is true:
3839

3940
## Expectation
4041

41-
For each target element, all [text nodes][] in the [visible text content][] either match or are contained within the [accessible name][] of this target element, except for characters in the [text nodes][] used to express [non-text content][]. Leading and trailing [whitespace][] and difference in case sensitivity should be ignored.
42+
For each target element, the [visible inner text][] is contained within the [accessible name][] of the target element according to the [label in name algorithm][].
4243

4344
## Assumptions
4445

46+
This rule assumes that the [visible inner text][] is equal to the [label][https://www.w3.org/WAI/WCAG21/Understanding/label-in-name#dfn-label] in most cases (enough cases to be useful) even though "label" is not precisely defined at this point in history.
47+
48+
This rule assumes that neither the label nor the [visible inner text][] are rearranged with CSS in some way so that they appear to the user in a different order than they do in the DOM.
49+
4550
This rule assumes that all resources needed for rendering the page are properly loaded. Checking if resources are missing is out of the scope of rules. Missing resources may be rendered as text (for example, missing `img` are rendered as their `alt` attribute).
4651

4752
## Accessibility Support
@@ -54,6 +59,7 @@ This rule applies to elements with a [widget role][] that [support name from con
5459

5560
The understanding document of [2.5.3 Label in Name][understand253] use the term "symbolic text characters" to refer to a type of [non-text content][] that uses text characters as symbols, such as using "x" to mean "close". This rule considers them as "characters expressing non-text content". Unicode emojis are another example of characters expressing non-text content, although these are not "symbolic text characters".
5661

62+
5763
### Bibliography
5864

5965
- [Understanding Success Criterion 2.5.3: Label in Name][understand253]
@@ -65,39 +71,39 @@ The understanding document of [2.5.3 Label in Name][understand253] use the term
6571

6672
#### Passed Example 1
6773

68-
This link has [visible][] text that matches the [accessible name][].
74+
This link has [visible inner text][] that is equal to the [accessible name][].
6975

7076
```html
7177
<a href="https://act-rules.github.io/" aria-label="ACT rules">ACT rules</a>
7278
```
7379

7480
#### Passed Example 2
7581

76-
This link has [visible][] text that, ignoring trailing whitespace, matches the [accessible name][].
82+
This link has [visible inner text][] that, ignoring whitespace, is equal to the [accessible name][].
7783

7884
```html
79-
<a href="https://act-rules.github.io/" aria-label=" ACT rules ">ACT rules</a>
85+
<a href="https://act-rules.github.io/" aria-label=" ACT rules ">ACT rules</a>
8086
```
8187

8288
#### Passed Example 3
8389

84-
This link has [visible][] text that, ignoring case, matches the [accessible name][].
90+
This link has [visible inner text][] that, ignoring case, is equal to the [accessible name][].
8591

8692
```html
87-
<a href="https://act-rules.github.io/" aria-label="act rules">ACT rules</a>
93+
<a href="https://act-rules.github.io/" aria-label="act Rules">ACT rules</a>
8894
```
8995

9096
#### Passed Example 4
9197

92-
This button has [visible][] text that is contained within the [accessible name][].
98+
This button has [visible inner text][] that is contained within the [accessible name][] according to the [label in name algorithm][].
9399

94100
```html
95101
<button aria-label="Next Page in the list">Next Page</button>
96102
```
97103

98104
#### Passed Example 5
99105

100-
This button has [visible][] text that does not need to be contained within the [accessible name][], because the "x" text node is [non-text content][].
106+
The "X" is [non-text content][], so it doesn't need to be contained within the [accessible name][].
101107

102108
```html
103109
<button aria-label="close">X</button>
@@ -117,45 +123,242 @@ This `button` element has the text "search" rendered as an magnifying glass icon
117123
<button aria-label="Find">search</button>
118124
```
119125

126+
#### Passed Example 7
127+
128+
This button has [visible inner text][] that, according to the [label in name algorithm][], is contained within the [accessible name][]. This example shows why the [label in name algorithm][] uses the [visible inner text][] and not the [visible text content][]: the <p> tags insert whitespace into the result in the former but not the latter.
129+
130+
```html
131+
<button aria-label="Hello world"><p>Hello</p><p>world</p></button>
132+
```
133+
134+
#### Passed Example 8
135+
136+
Similar to the previous example.
137+
138+
```html
139+
<a href="#" aria-label="Some article by John Doe"><h6>Some article</h6><p>by John Doe</p></a>
140+
```
141+
142+
#### Passed Example 9
143+
144+
The [visible inner text][] is "Download specification". The words "the" and "gizmo" aren't part of it.
145+
146+
```html
147+
<a aria-label="Download specification" href="#">Download <span style="visibility: hidden">the</span> <span style="display: none">gizmo</span> specification</a>
148+
```
149+
150+
#### Passed Example 10
151+
152+
This example shows that the [visible inner text][] isn't always the same as the [innerText][https://html.spec.whatwg.org/multipage/dom.html#the-innertext-idl-attribute]. The visible inner text is "Download specification". The innerText is 'Download \ngizmo\nspecification'. This rule uses the visible inner text - not innerText.
153+
154+
```html
155+
<style>
156+
.visually-hidden {
157+
/* Source: https://www.tpgi.com/the-anatomy-of-visually-hidden/ */
158+
clip-path: inset(50%);
159+
height: 1px;
160+
overflow: hidden;
161+
position: absolute;
162+
white-space: nowrap;
163+
width: 1px;
164+
}
165+
</style>
166+
<a aria-label="Download specification" href="#">Download <span class="visually-hidden">gizmo</span> specification</a>
167+
```
168+
169+
#### Passed Example 11
170+
171+
This example shows that the [label in name algorithm][] handles many kinds of whitespace.
172+
173+
```html
174+
<a aria-label="compose email" href="#">compose &nbsp;&nbsp;<br> email</a>
175+
```
176+
177+
#### Passed Example 12
178+
179+
This example passes the rule because "YYYY-MM-DD" is in brackets. Text in brackets is removed by the [label in name algorithm][], because its not normally spoken by speech-input users.
180+
181+
```html
182+
<button aria-label="Search by date">Search by date (YYYY-MM-DD)</button>
183+
```
184+
185+
#### Passed Example 13
186+
187+
The passes for two reasons: 1) because the ellipsis ("…") is [non-text content][], and 2) because the ellipsis is neither a letter nor a digit and so is filtered out by the [label in name algorithm][].
188+
189+
```html
190+
<button aria-label="Next">Next…</button>
191+
```
192+
193+
#### Passed Example 14
194+
195+
This passes because the [label in name algorithm][] effectively ignores all punctuation and emoji, in both the visible inner text and the accessible name, as long as they don't break up words.
196+
197+
```html
198+
<button aria-label="💡 Submit 💡">>>> ** Submit ** <<<</button>
199+
```
200+
201+
#### Passed Example 15
202+
203+
The "X" is non-text content.
204+
205+
```html
206+
<button aria-label="Close">X</button>
207+
```
208+
209+
210+
120211
### Failed
121212

122213
#### Failed Example 1
123214

124-
This link has [visible][] text that is different from the [accessible name][].
215+
This link has [visible inner text][] that is very different from the [accessible name][].
125216

126217
```html
127218
<a href="https://act-rules.github.io/" aria-label="WCAG">ACT rules</a>
128219
```
129220

130221
#### Failed Example 2
131222

132-
This button has [visible][] text that is only partially contained within the [accessible name][].
223+
This button has [visible inner text][] that is only partially contained within the [accessible name][].
133224

134225
```html
135226
<button aria-label="the full">The full label</button>
136227
```
137228

138-
#### Failed Example 3
229+
#### Failed Example 3
230+
231+
This button has [visible inner text][] that is fully contained within the [accessible name][] when viewed as a character-by-character substring. But that does not satisfy our [label in name algorithm][], which works on full words. So this fails the rule.
232+
233+
```html
234+
<a href="#" aria-label="Discover Italy">Discover It</a>
235+
```
236+
237+
#### Failed Example 4
238+
239+
This link's [accessible name][] contains two tokens (according to the[label in name algorithm][]) and the [visible inner text][] contains one token. So it fails the rule.
240+
241+
```html
242+
<a aria-label="just ice" href="#">justice</a>
243+
```
244+
245+
#### Failed Example 5
246+
247+
This link has an [accessible name][] which contains a hyphen. The [label in name algorithm][] breaks up words on hyphens. So it turns "non-standard" into two tokens: "non" and "standard". So this fails the rule.
248+
249+
```html
250+
<a href="#" aria-label="non-standard">nonstandard</a>
251+
```
252+
253+
#### Failed Example 6
254+
255+
The rule has no special handling for acronyms or initialisms.
256+
257+
```html
258+
<a aria-label="WAVE" href="#">W A V E</a>
259+
```
260+
261+
#### Failed Example 7
262+
263+
The rule has no special handling for abbreviations.
264+
265+
```html
266+
<a aria-label="University Avenue" href="#">University Ave.</a>
267+
```
268+
269+
#### Failed Example 8
139270

140-
This link has [visible][] text with mathematical symbols, that does not match the [accessible name][] because the mathematical symbols were written out in the accessible name. This is [explicitly mentioned in WCAG](https://www.w3.org/WAI/WCAG21/Understanding/label-in-name#mathematical-expressions-and-formulae).
271+
This link has [visible inner text][] with mathematical symbols and is not contained within the [accessible name][] because the mathematical symbols are represented as English words (not digits) in the accessible name. This is [explicitly mentioned in WCAG](https://www.w3.org/WAI/WCAG21/Understanding/label-in-name#mathematical-expressions-and-formulae).
141272

142273
```html
143274
<a href="/" aria-label="Proof of two multiplied by two is four">Proof of 2&times;2=4</a>
144275
```
145276

277+
#### Failed Example 9
278+
279+
Similar to the previous example. This rule has no special handling for converting mathematical symbols into words, or vice versa.
280+
281+
```html
282+
<button aria-label="11 times 3 equals 33">11×3=33</button>
283+
```
284+
285+
#### Failed Example 10
286+
287+
This button's accessible name contains the same tokens that are in the visible label. But they aren't in the same order, so it fails the sublist check part of the [label in name algorithm][], and so it fails the rule.
288+
289+
```html
290+
<button aria-label="how are you"><span>you</span><span>how</span><span>are</span></button>
291+
```
292+
293+
#### Failed Example 11
294+
295+
This link's accessible name contains the same digits that are in the visible label, and in the same order. But they have different spaces and punctuation between them, so they are considered separate tokens. So this fails the rule.
296+
297+
```html
298+
<a aria-label="Call 1 2 3. 4 5 6. 7 8 9 0." href="tel:1234567890">123.456.7890</a>
299+
```
300+
301+
#### Failed Example 12
302+
303+
This rule has no special handling which tries to guess when number have the same semantic meaning. It operates on tokens only.
304+
305+
```html
306+
<a href="#2021" aria-label="20 21">2021</a>
307+
```
308+
309+
#### Failed Example 13
310+
311+
Similar to the previous example.
312+
313+
```html
314+
<a aria-label="fibonacci: 0 1 1 2 3 5 8 13 21 34">fibonacci: 0112358132134</a>
315+
```
316+
317+
#### Failed Example 14
318+
319+
This rule has no special handling for converting digits into words, or vice versa.
320+
321+
```html
322+
<a href="#2021" aria-label="twenty twenty-one">two thousand twenty-one</a>
323+
```
324+
325+
#### Failed Example 15
326+
327+
(Same as above.) This rule has no special handling for converting digits into words, or vice versa.
328+
329+
```html
330+
<a aria-label="two zero two three" href="#">2 0 2 3</a>
331+
```
332+
333+
#### Failed Example 16
334+
335+
This rule has no special handling for digits that appear next to letters with no spaces in between.
336+
337+
```html
338+
<a aria-label="1a" href="#">1</a>
339+
```
340+
341+
#### Failed Example 17
342+
343+
The definition of [visible inner text][] doesn't treat text any differently if it's excluded from the accessibility tree with aria-hidden. So this rule effectively ignores aria-hidden. So this element fails the rule.
344+
345+
```html
346+
<a aria-label="Download specification" href="#">Download <span aria-hidden="true">gizmo</span> specification</a>
347+
```
348+
146349
### Inapplicable
147350

148351
#### Inapplicable Example 1
149352

150-
This `nav` is not a widget, so the [visible][] text does not need to match the [accessible name][].
353+
This `nav` is not a widget, so the [visible inner text][] does not need to match the [accessible name][].
151354

152355
```html
153356
<nav aria-label="main nav">W3C navigation</nav>
154357
```
155358

156359
#### Inapplicable Example 2
157360

158-
This email text field does not need to have its [visible][] text match the [accessible name][]. The content of a textfield shows its value instead of its label; it does not [support name from content][supports name from content]. The label is usually adjacent to the textfield instead.
361+
This email text field does not need to have its [visible inner text][] match the [accessible name][]. The content of a textfield shows its value instead of its label; it does not [support name from content][supports name from content]. The label is usually adjacent to the textfield instead.
159362

160363
```html
161364
<div>E-mail</div>
@@ -164,15 +367,15 @@ This email text field does not need to have its [visible][] text match the [acce
164367

165368
#### Inapplicable Example 3
166369

167-
This `div` element does not have a widget role, so the [visible][] text does not need to match the [accessible name][].
370+
This `div` element does not have a widget role, so the [visible inner text][]t does not need to match the [accessible name][].
168371

169372
```html
170373
<div role="tooltip" aria-label="OK">Next</div>
171374
```
172375

173376
#### Inapplicable Example 4
174377

175-
This link has no [visible text content][].
378+
This link has no [visible inner text][].
176379

177380
```html
178381
<a href="https://w3.org" aria-label="W3C homepage">
@@ -186,6 +389,7 @@ This link has no [visible text content][].
186389
[semantic role]: #semantic-role 'Definition of Semantic role'
187390
[supports name from content]: https://www.w3.org/TR/wai-aria-1.1/#namefromcontent 'Definition of Supports name from contents'
188391
[visible]: #visible 'Definition of visible'
392+
[visible inner text]: #visible-inner-text 'Definition of Visible inner text'
189393
[visible text content]: #visible-text-content 'Definition of Visible text content'
190394
[whitespace]: #whitespace 'Definition of Whitespace'
191395
[widget role]: https://www.w3.org/TR/wai-aria-1.1/#widget_roles 'Definition of Widget role'

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@
4848
"name": "Dagfinn Rømen",
4949
"url": "https://github.com/DagfinnRomen"
5050
},
51+
{
52+
"name": "Dan Tripp",
53+
"url": "https://github.com/dan-tripp-siteimprove"
54+
},
5155
{
5256
"name": "Daniël Strik",
5357
"url": "https://github.com/danistr"
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
title: Label in Name Algorithm
3+
key: label-in-name-algorithm
4+
unambiguous: true
5+
objective: false
6+
input_aspects:
7+
- CSS styling
8+
- DOM tree
9+
---
10+
11+
Let 'label' be the [visible inner text][] of the target element. Let 'name' be the [accessible name][] of the target element. Both 'label' and 'name' are strings.
12+
13+
Sub-algorithm to tokenize a string:
14+
15+
- Convert the string to lower case.
16+
- For each character that either a) represents non-text content, or b) isn't a letter or a digit: replace that character with a space character.
17+
- For a) Judgement of "non-text" probably can't be fully automated. eg. "X" for "close" probably can be, but presumably there are more cases than this.
18+
- For b) Use the unicode classes Letter, Mark, and "Number, Decimal Digit [Nd]". (This will exclude hyphens, punctuation, emoji, and more.)
19+
- Remove all characters that are within parentheses (AKA round brackets).
20+
- Ignore square brackets and braces.
21+
- Split the string into a list of strings, using a whitespace regular expression as the separator.
22+
- This 'split' operation must:
23+
- Effectively remove leading and trailing whitespace as a pre-processing step.
24+
- If the string was all whitespace before this operation: result in an empty list.
25+
26+
Then do the check: is the tokenized 'label' a sublist of the tokenized 'name'?
27+
- This 'sublist' check has these properties:
28+
- It checks whether elements are consecutive or not. i.e. it checks for a substring, in the computer science sense of the term. Not a subsequence.
29+
- An empty list is a sublist of any list.
30+
31+
If the answer is "yes" (i.e. the tokenized 'label' a sublist of the tokenized 'name'), then the target element passes the rule. Otherwise, it fails the rule.
32+
33+
[accessible name]: #accessible-name 'Definition of accessible name'
34+
[visible inner text]: #visible-inner-text 'Definition of Visible inner text'

0 commit comments

Comments
 (0)