Skip to content

Rule 2ee8b8 ("Visible label is part of accessible name"): introducing a new "label in name algorithm". #2075

Open
dan-tripp-siteimprove wants to merge 100 commits into
act-rules:developfrom
dan-tripp-siteimprove:rule-2ee8b8-may-2023
Open

Rule 2ee8b8 ("Visible label is part of accessible name"): introducing a new "label in name algorithm". #2075
dan-tripp-siteimprove wants to merge 100 commits into
act-rules:developfrom
dan-tripp-siteimprove:rule-2ee8b8-may-2023

Conversation

@dan-tripp-siteimprove
Copy link
Copy Markdown
Collaborator

@dan-tripp-siteimprove dan-tripp-siteimprove commented Jun 22, 2023

<< Describe the changes >>

Closes issue(s):

Need for Call for Review:
This will require a 2 weeks Call for Review


Pull Request Etiquette

When creating PR:

  • [ x] Make sure you're requesting to pull a branch (right side) to the develop branch (left side).
  • [x ] Make sure you do not remove the "How to Review and Approve" section in your pull request description

After creating PR:

  • [ x] Add yourself (and co-authors) as "Assignees" for PR.
  • [ x] Add label to indicate if it's a Rule, Definition or Chore.
  • [x ] Link the PR to any issue it solves. This will be done automatically by referencing the issue at the top of this comment in the indicated place.
  • [ x] Optionally request feedback from anyone in particular by assigning them as "Reviewers".

When merging a PR:

  • Close any issue that the PR resolves. This will happen automatically upon merging if the PR was correctly linked to the issue, e.g. by referencing the issue at the top of this comment.

How to Review And Approve

  • Go to the “Files changed” tab
  • Here you will have the option to leave comments on different lines.
  • Once the review is completed, find the “Review changes” button in the top right, select “Approve” (if you are really confident in the rule) or "Request changes" and click “Submit review”.
  • Make sure to also review the proposed Call for Review period. In case of disagreement, the longer period wins.

@dan-tripp-siteimprove dan-tripp-siteimprove added Rule Update Use this label for an existing rule that is being updated reviewers wanted labels Jun 22, 2023
@dan-tripp-siteimprove dan-tripp-siteimprove self-assigned this Jun 22, 2023
@dan-tripp-siteimprove dan-tripp-siteimprove changed the title Rule 2ee8b8 may 2023 Rule 2ee8b8 ("Visible label is part of accessible name"): introducing a new "label in name algorithm". Jun 22, 2023
@WilcoFiers
Copy link
Copy Markdown
Member

@dan-tripp-siteimprove Since this is being worked on still by @kengdoj, can we set this to draft?

@dan-tripp-siteimprove dan-tripp-siteimprove marked this pull request as draft July 20, 2023 21:19
@dan-tripp-siteimprove
Copy link
Copy Markdown
Collaborator Author

@dan-tripp-siteimprove Since this is being worked on still by @kengdoj, can we set this to draft?

Done

Jym77
Jym77 previously requested changes Nov 9, 2023
Copy link
Copy Markdown
Collaborator

@Jym77 Jym77 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good. I like the details and the many new examples that explicit the decisions we've taken.

Comment thread _rules/visible-label-in-accessible-name-2ee8b8.md
Comment thread _rules/visible-label-in-accessible-name-2ee8b8.md Outdated
Comment thread pages/glossary/visible-inner-text.md Outdated
Comment thread pages/glossary/visible-inner-text.md Outdated

The <dfn id="for-text">visible inner text of a [text node][]</dfn> is:
- if the [text node][] is [visible][], its visible inner text is its [data][];
- if the [text node][] is not-[visible][], [rendered][], and contains only [whitespace][], its visible inner text is the string `" "` (a single ASCII whitespace);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The conditional here sounds a bit weird 🤔
Notably, a text node that is not visible, rendered, and contains more than whitespace (e.g. in <span style="visibility: hidden">Hello</span>) would not trigger it and therefore have an empty string as visible inner text (rather than a whitespace).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting question. I don't know the answer. But I'll note that I copied this definition from sanshikan so if it needs fixing here, it probably needs fixing there too.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, doing some archaeology, this is due to the fact that whitespace are not visible per our definition…

<button aria-label="hello world"><span>hello</span><span id="space"> </span><span>world</span></button>

The span#space is not visible (and neither is its child text node). So the first bullet doesn't apply. Without the second bullet, the visible inner text of the button would be helloworld, not matching the accessible name of hello world due to spacing…
I guess we need to add an example to show that.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in b2df021

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This raises another question: what should we do with this?
<a aria-label="Download specification" href="#"><span>Download</span><span style="visibility: hidden">x</span><span>specification</span></a>
According to the current definition, because of the clause "contains only [whitespace][]", the visible inner text of the <a> element is "Downloadspecification". Visually it looks like "Download specification". So I wonder if we could remove the clause "contains only [whitespace][]". What do you think?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point 🤔 But if the span was invisible due to absolute positioning out of viewport, it shrould be removed:

<a aria-label="Download specification" href="#"><span>Download</span><span style="position: absolute; left: -9999px">x</span><span>specification</span></a>

I guess the true condition is whether it creates a CSS box that lies somewhere between the ones of the rest of the text taking part in the computation (and isn't fully contained in them), or something like that 🙈
Or maybe we just make the special case for visibility: hidden and assume that these is already a corner case and that it won't create too many true problems (We've been using that definition in Alfa for two years and I don't remember seeing a problem caused by it, so it may be safe to assume that it is a good enough approximation).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has given me a lot to think about. I'll try to bring it up in our next one-on-one meeting.

Comment thread pages/glossary/visible-inner-text.md Outdated
Comment thread pages/glossary/visible-inner-text.md Outdated
Comment thread pages/glossary/visible-inner-text.md Outdated
Comment thread pages/glossary/visible-inner-text.md Outdated
Comment thread pages/glossary/label-in-name-algorithm.md
Comment thread pages/glossary/label-in-name-algorithm.md Outdated
dan-tripp-siteimprove and others added 8 commits November 9, 2023 11:42
…://github.com/Siteimprove/sanshikan/blob/main/terms/visible-inner-text.md)

- changing glossary links' prefixes from "./" to "#".  I don't know if the former was working or not.  but the latter is the common practice, it seems.
Co-authored-by: Jean-Yves Moyen <jym@siteimprove.com>
Co-authored-by: Jean-Yves Moyen <jym@siteimprove.com>
…placing it with a new idea: the algorithm 'return value' eg. 'returns "is contained"'.

- rewording rule expectation.  I think that 'For the target element' is better than 'For each target element' because for this rule, the computation of the expecation for each applicable target element is done in isolation from the other applicable targets on the page.  It's simpler if the "for loop" over all applicable targets is done by the tool, not the rule.
@Jym77 Jym77 dismissed their stale review November 10, 2023 09:15

Changes done

dan-tripp-siteimprove and others added 20 commits April 16, 2026 19:25
Co-authored-by: Jean-Yves Moyen <jym@siteimprove.com>
Also removing whitespace between the divs.  Doing this because that whitespace was introduced accidentally in commit 5617755 (which was a merge).
Co-authored-by: Jean-Yves Moyen <jym@siteimprove.com>
Co-authored-by: Jean-Yves Moyen <jym@siteimprove.com>
Co-authored-by: Jean-Yves Moyen <jym@siteimprove.com>
Co-authored-by: Jean-Yves Moyen <jym@siteimprove.com>
as per act-rules#2075 (comment)
this fixes a big problem that has been there since the beginning of this PR i.e. three years.
@Jym77 Jym77 removed the Agenda item label Apr 27, 2026
Copy link
Copy Markdown
Collaborator

@Jym77 Jym77 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Many small editorial clean up.


This rule assumes that the visible label doesn't use CSS to add whitespace where none exists in the DOM.

This rule - specifically, the [label in name algorithm][] that this rule relies on - assumes that content within parentheses can be ignored. ("Parentheses" are also known as "round brackets".) This is important becuase the algorithm's treatment of parentheses is to remove them and all characters within them. This assumption is almost always true in English. Exceptions include links with names such "Dune (1984 film)" and "Dune (2021 film)". This assumption is known to be often false in languages other than English, such as German (where parentheses indicate dual states) and Arabic (where parentheses are often used as quotation marks). Violations of this assumption will, in real-world scenarios, more often result in a false negative for this rule rather than a false positive.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This rule - specifically, the [label in name algorithm][] that this rule relies on - assumes that content within parentheses can be ignored. ("Parentheses" are also known as "round brackets".) This is important becuase the algorithm's treatment of parentheses is to remove them and all characters within them. This assumption is almost always true in English. Exceptions include links with names such "Dune (1984 film)" and "Dune (2021 film)". This assumption is known to be often false in languages other than English, such as German (where parentheses indicate dual states) and Arabic (where parentheses are often used as quotation marks). Violations of this assumption will, in real-world scenarios, more often result in a false negative for this rule rather than a false positive.
This rule specifically, the [label in name algorithm][] that this rule relies on assumes that content within parentheses can be ignored ("Parentheses" are also known as "round brackets"). This is important because the algorithm's treatment of parentheses is to remove them and all characters within them. This assumption is almost always true in English. Exceptions include links with names such "Dune (1984 film)" and "Dune (2021 film)". This assumption is known to be often false in languages other than English, such as German (where parentheses indicate dual states) and Arabic (where parentheses are often used as quotation marks). Violations of this assumption will, in real-world scenarios, more often result in a false negative for this rule rather than a false positive.

#### Passed Example 5

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][]. Note: this would need to meet SC 1.1.1 Non text content.
This button has [visible inner text][] that does not need to be contained within the [accessible name][], because the "x" text node is [non-text content][]. Note: this would need to meet SC 1.1.1 Non text content.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This button has [visible inner text][] that does not need to be contained within the [accessible name][], because the "x" text node is [non-text content][]. Note: this would need to meet SC 1.1.1 Non text content.
This button has [visible inner text][] that does not need to be contained within the [accessible name][], because the "X" text node is [non-text content][]; the [label in name algorithm][] therefore ignores it. Note: this would need to meet SC 1.1.1 Non text content.

#### Passed Example 6

This `button` element has the text "search" rendered as an magnifying glass icon by the font. Because the text is rendered as [non-text content][], the text does not need to be contained within the [accessible name][].
This `button` element has the text "search" rendered as a magnifying glass icon by the font. Because the text is rendered as [non-text content][], the text does not need to be contained within the [accessible name][].
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This `button` element has the text "search" rendered as a magnifying glass icon by the font. Because the text is rendered as [non-text content][], the text does not need to be contained within the [accessible name][].
This `button` element has the text "search" rendered as a magnifying glass icon by the font. Because the text is rendered as [non-text content][], the text does not need to be contained within the [accessible name][]; and the [label in name algorithm][] ignores it.


#### Passed Example 9

The [visible inner text][] of this link is "ACT" (with no spaces) because of the explicit styles of `display: inline` on the `p` elements and the absence of whitespace between the `div` elements. The cases of `display: inline` and `display: block` are handled by the definition of [visible inner text of an element][]. This example shows that the definition agrees with the visual rendering done by the browser.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The [visible inner text][] of this link is "ACT" (with no spaces) because of the explicit styles of `display: inline` on the `p` elements and the absence of whitespace between the `div` elements. The cases of `display: inline` and `display: block` are handled by the definition of [visible inner text of an element][]. This example shows that the definition agrees with the visual rendering done by the browser.
The [visible inner text][] of this link is "ACT" (with no spaces) because of the explicit styles of `display: inline` on the `div` elements and the absence of whitespace between them. The cases of `display: inline` and `display: block` are handled by the definition of [visible inner text of an element][]. This example shows that the definition agrees with the visual rendering done by the browser.


The <dfn id="visible-inner-text:for-text">visible inner text of a [text node][]</dfn> is:
1. if the [text node][] is [visible][], its visible inner text is its [data][] with whitespace normalized by replacing contiguous [whitespace][] with `" "` (U+0020 SPACE);
1. <span id="visible-inner-text:for-text-clause-2">if the [text node][] is not [visible][], is [rendered][], and contains only [whitespace][], its visible inner text is `" "` (U+0020 SPACE);</span>
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: it may be nicer, both here and for references, to name the clauses and use a dfn element around the name. Something like:

Suggested change
1. <span id="visible-inner-text:for-text-clause-2">if the [text node][] is not [visible][], is [rendered][], and contains only [whitespace][], its visible inner text is `" "` (U+0020 SPACE);</span>
1. (<dfn id="visible-inner-text:text-whitespace>Whitespace</dfn>): if the [text node][] is not [visible][], is [rendered][], and contains only [whitespace][], its visible inner text is `" "` (U+0020 SPACE);

Obviously, it needs to be done on all clauses for consistency to make sense. But in a fairly complex definition like this one, it can also help discussing it.

- Effectively remove leading and trailing [whitespace][].
- If the input string contains nothing but [whitespace][] before this operation: return an empty list.
- In English and most other European languages, a greedy [whitespace][] regular expression will accomplish this. In languages such as Thai, Chinese, and Japanese, it won't.
- A consequence of using the ACT definition of [whitespace][] here is that all kinds of whitespace are covered. That includes the Unicode code point U+00A0 NO-BREAK SPACE (NBSP), which can be represented by the HTML named character reference `&nbsp;`.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- A consequence of using the ACT definition of [whitespace][] here is that all kinds of whitespace are covered. That includes the Unicode code point U+00A0 NO-BREAK SPACE (NBSP), which can be represented by the HTML named character reference `&nbsp;`.
- A consequence of using the ACT definition of [whitespace][] here is that all kinds of whitespace are covered. That includes the Unicode code point U+00A0 NO-BREAK SPACE (NBSP), which can be represented by the HTML named character reference `&nbsp;`.

Then do the check: is the tokenized `label` a contiguous subsequence of the tokenized `name`?
- This 'contiguous subsequence' check has these properties:
- Each string comparison (between a list element in the tokenized label and a list element in the tokenized name) is a simple string equality check.
- The "contiguous" aspect means that it's crucial that the elements are consecutive in the original list. Put another way: a contiguous subsequence of X can be obtained by removing any number of tokens from the start and/or end (but not the middle) of X. For example: ["A", "B", "C"] is a contiguous subsequence of ["A", "B", "C", "D"]. ["A", "B", "D"] is not.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- The "contiguous" aspect means that it's crucial that the elements are consecutive in the original list. Put another way: a contiguous subsequence of X can be obtained by removing any number of tokens from the start and/or end (but not the middle) of X. For example: ["A", "B", "C"] is a contiguous subsequence of ["A", "B", "C", "D"]. ["A", "B", "D"] is not.
- The "contiguous" aspect means that it's crucial that the elements are consecutive in the original list. Put another way: a contiguous subsequence of X can be obtained by removing any number of tokens from the start and/or end (but not the middle) of X. For example: ["A", "B", "C"] is a contiguous subsequence of ["A", "B", "C", "D"]; but ["A", "B", "D"] is not.

- DOM tree
---

(The "visible inner text" defined here is similar to, but not the same as, [visible text content][] and [innerText](https://html.spec.whatwg.org/multipage/dom.html#the-innertext-idl-attribute).)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Maybe move that to a Background section at the end of the definition? It looks weird starting the definition with a parenthesis.


The <dfn id="visible-inner-text:for-text">visible inner text of a [text node][]</dfn> is:
1. if the [text node][] is [visible][], its visible inner text is its [data][] with whitespace normalized by replacing contiguous [whitespace][] with `" "` (U+0020 SPACE);
1. <span id="visible-inner-text:for-text-clause-2">if the [text node][] is not [visible][], is [rendered][], and contains only [whitespace][], its visible inner text is `" "` (U+0020 SPACE);</span>
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: You can also try and name the bullet, which can be convenient for a complex definition like this one, and makes it easier to define anchors.

Suggested change
1. <span id="visible-inner-text:for-text-clause-2">if the [text node][] is not [visible][], is [rendered][], and contains only [whitespace][], its visible inner text is `" "` (U+0020 SPACE);</span>
1. **(<dfn id="visible-inner-text:text-whitespace">Whitespace</dfn>):** if the [text node][] is not [visible][], is [rendered][], and contains only [whitespace][], its visible inner text is `" "` (U+0020 SPACE);

The bolding and parenthesis should make it visually obvious that it is not part of the definition. Obviously, it needs to be done on all items in a list if it is done on any.

1. if the [element][] is [rendered][] and not [visible][] and has a [bounding box][] which has width greater than 0, its visible inner text is `" "` (U+0020 SPACE);
1. if the [element][] is [rendered][] and not [visible][] and has a [bounding box][] which has width of 0, its visible inner text is `""` (the empty string);
1. if the [element][] is a [`<br>`][<br>] element, its visible inner text is `"\n"` (U+000A END OF LINE).
1. if the [computed][] [`display`][display] property of the [element][] has an [outer display type][] of `block`, or an [inner display type][] of `table-caption`, the visible inner text of the [element][] is the concatenation of is `"\n"` (U+000A END OF LINE) plus the visible inner text of its children (in [tree order][] in the [flat tree][]) plus another `"\n"` (U+000A END OF LINE);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
1. if the [computed][] [`display`][display] property of the [element][] has an [outer display type][] of `block`, or an [inner display type][] of `table-caption`, the visible inner text of the [element][] is the concatenation of is `"\n"` (U+000A END OF LINE) plus the visible inner text of its children (in [tree order][] in the [flat tree][]) plus another `"\n"` (U+000A END OF LINE);
1. if the [computed][] [`display`][display] property of the [element][] has an [outer display type][] of `block`, or an [inner display type][] of `table-caption`, the visible inner text of the [element][] is the concatenation of `"\n"` (U+000A END OF LINE) plus the visible inner text of its children (in [tree order][] in the [flat tree][]) plus another `"\n"` (U+000A END OF LINE);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Review Call 1 week Call for review for small changes Rule Update Use this label for an existing rule that is being updated

Projects

Status: In review