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 82 commits intoact-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 82 commits intoact-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

@WilcoFiers WilcoFiers moved this from Backlog to In progress in ACT Projects Mar 19, 2026
Sub-algorithm to tokenize a string:

1. Do Unicode [case folding][] on the string then convert it to [normalization form KD][].
1. 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.
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.

I understand that there is (or should be) a separate issue addressing non-latin languages, but IMO the current wording is overly strict. Japanese for example is not composed of letters. As a result, a string like "これは何ですか", per this bullet, gets replaced with seven whitespace characters, which is clearly incorrect and leads to invalid results. Given that the current/existing rule handles simple Japanese scenarios but the new one does not, IMO we can't proceed in this direction. We need a better definition of "letter or digit" that also accounts for ideographic writing systems; otherwise, this change would be a step backward.

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.

Fair point for sure, but I'm a little stumped as to how to fix this. Do you have any ideas?

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.

Wait a minute. I think that Japanese works out fine because they are "letters" according to Unicode. For example, see https://www.compart.com/en/unicode/U+3059 - it says "Category: Other Letter (Lo)". That is covered by my algorithm and won't be replaced by a space. I just pushed a commit which changes some small things, but does not change this case.

1. 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.
- For a) Judgment of "non-text" probably can't be fully automated. For example: "X" for "close" probably can be automated, but presumably there are more cases than this.
- For b) Use the Unicode classes Letter, Mark, and "Number, Decimal Digit [Nd]". (This will exclude hyphens, punctuation, emoji, and more.)
1. Remove parentheses (also known as round brackets) and all characters that are between an opening and closing parenthesis.
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.

We need to exclude anything that is a mathematical, regular, logical, or similar type of expression.
For example, in a multiple-answer quiz asking "Which of the following is correct?":

  • if ((a || b) && c)
  • if (a || b && c)

Here the parentheses make a difference so treating them as having the same accessible name would be invalid

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.

It's another fine puzzle. How could we exclude such things? Change this:
Remove parentheses (also known as round brackets) and all characters that are between an opening and closing parenthesis.
to this?
Remove parentheses (also known as round brackets) and all characters that are between an opening and closing parenthesis, unless the parentheses are part of a mathematical, regular, logical, or similar type of expression.

@patrickhlauke
Copy link
Copy Markdown
Contributor

At this stage, I don't have any concerns with the algorithm ... though we will probably need to revisit this if we widen the discussion (this was mentioned recently, but I can't find the email/issue for it) to add additional considerations such as making digits and their actual written out words (e.g. "1" and "one") be ok as synonyms (though this can possibly get hairy when having to decide if "123" is ok as BOTH "one two three" and/or "one hundred and twenty three" or even "one hundred twenty three")

- changing unicode wording.   class -> category.
- excluding "Mark".  I don't know how "mark" got in there, and I think it should not have been in there.
@WilcoFiers WilcoFiers moved this from In progress to In review in ACT Projects Apr 2, 2026
@dan-tripp-siteimprove dan-tripp-siteimprove added the Review Call 1 week Call for review for small changes label Apr 13, 2026
@Jym77 Jym77 mentioned this pull request Apr 14, 2026
8 tasks
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.

  • Please get #2403 merged in first to clean up the autogenerated changelogs (no need to have a "label in name algorithm" entry in the changelog of the "keyboard trap" rule).
  • Many small polishes, some larger ones.
  • Note that it is possible to get specific "examples for definition" pages, e.g. Example of Visible which can be a way to alleviate the many examples inside the rule that mostly illustrate the definition (while actually giving more examples of corner cases of the definition). OTOH, these examples for definitions are not included in the tests in any way, so implementers can take inspiration from them but there is no "validation of implementation" See also #2087.

I do like the way it goes 😀

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

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 the algorithm's treatment of parentheses is appropriate in the given human language. "Parentheses" are also known as "round brackets". The algorithm's treatment of parentheses is to remove them and all characters within them. This assumption can be reworded as: content within parentheses can be ignored. This assumption is almost always true in English. It is known to be often false in other languages, 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.

Issue: I am a bit uncomfortable in stating an assumption and immediately saying that it is often not met 😓
I think the bottom line is OK as it is indeed, "only" false negatives. But I think it should be rephrased and maybe moved to Background (like the "image of text" discussion).
Something like "In languages where parenthesis are used for non-incidental [or whatever the correct grammatical term] content, this rule may pass while 2.5.3 fails because a parenthesis is present on one side and its content matter. Examples of such languages include Arabic and German [putting the languages in alphabetical order]" (with a bit more meat to that text, but essentially what is in the current one).

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.

I'm not sure I completely agree. I am very comfortable stating an assumption and immediately saying that it is often not met ... if that's true and helpful. I have spent enough hours trying to decipher specs - WCAG, ACT, you name it - wishing they would be more straightforward and not try to hide their warts. I think that WCAG has a serious problem in this area. ACT doesn't AFAICS, but I am loathe to move the needle even the tiniest amount in that direction. Your thoughts?

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.

I'm certainly not advocating to remove it totally, but moving it to background like the "image of text" note. That note could as well be phrased as "this rule assumes that the page has not image of text".
I'd rather keep assumptions for rare cases.

Not blocking for me however.

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.

I see this as an argument to move the "image of text" note to the "Assumptions" section, not to move the parentheses note to the "Background" section. :)

I had a conversation with someone you know at CSUN. He also saw assumption violations as rare things. I guess I don't. I just looked at my database and found 127 assumption violations for alfa's target size rules. Customers dispute those due to the "equivalent" exception of the SC == assumption of the alfa rule. We've had the target size rules for exactly two years. 127/(52*2) = 1.2 assumption violations per week. Whether that meets the definition of "rare" depends on one's perspective. It's small compared to other things. But still happens regularly (= 1.2 times per week).

At any rate, if it's not a blocker for you, I'll leave it as is - and thank you for the discussion. If someone else weighs in, I'll take it from there.

Comment thread pages/glossary/label-in-name-algorithm.md Outdated
- For b) Use the Unicode general categories "L" (Letter) and "N" (Number). (This will exclude hyphens, punctuation, emoji, and more.)
1. Remove parentheses (also known as round brackets) and all characters that are between an opening and closing parenthesis.
- Don't do this for square brackets, nor braces.
1. Split the string into a list of strings, one string per word, according to the word segmentation rules for the inherited programmatic language.
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: We should have a link for "inherited programmatic language" (of the element), which I realise is tricky because the existing definition goes the other way around.

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.

Oh dear. Would switching to most common element language help?

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.

🤔 I guess so, it depends whether we want to act on the lang attribute or the actual language…

OTOH, it looks like HTML definition of language is already what we need 😄

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.

Right on - I just did it in commit 3586285

[element]: https://dom.spec.whatwg.org/#element
[normalization form KD]: https://www.unicode.org/glossary/#normalization_form_kd
[visible inner text]: #visible-inner-text 'Definition of Visible inner text'
[whitespace][]: #whitespace 'Definition of 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.

Suggested change
[whitespace][]: #whitespace 'Definition of whitespace'
[whitespace]: #whitespace 'Definition of whitespace'

- 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 - the "No-Break Space" - which can be represented by the HTML named character reference `&nbsp;`.

Then do the check: is the tokenized 'label' a sublist of the tokenized '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
Then do the check: is the tokenized 'label' a sublist of the tokenized 'name'?
Then do the check: is the tokenized `label` a sublist of the tokenized `name`?


Then do the check: is the tokenized 'label' a sublist of the tokenized 'name'?
- This 'sublist' 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.
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: "Contiguous subsequence" or "subarray" seem to be the commonly used terms, but I do not find a reference that would be authoritative enough to be pointed here :-/

Maybe this comparison can be rephrased as "check whether the tokenised label list can be obtained by removing any number of tokens from the start and/or end of the tokenised name list"?

dan-tripp-siteimprove and others added 17 commits April 15, 2026 21:57
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>
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>
Also removing whitespace between the divs.  Doing this because that whitespace was introduced accidentally in commit 5617755 (which was a merge).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Agenda item 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