Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
wants to merge 48 commits into
base: develop
Choose a base branch
from

Conversation

dan-tripp-siteimprove
Copy link
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
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
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
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.


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
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
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
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
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
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
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
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.

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.
…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
Copy link
Collaborator Author

Ok I see - at least, partly. There are parts of this that are over my head but still I can see now that this identifies a real category of false positives which weren't discussed until now.

@dan-tripp-siteimprove
Copy link
Collaborator Author

Even so - again it seems to me that these whitespace cases shouldn't block this PR, because this PR didn't create them and doesn't make them worse. So using the strategy of incremental improvement (rather than perfection in one fell swoop): @dd8 what do you think of a separate PR for handling these whitespace cases?

@dd8
Copy link
Collaborator

dd8 commented Oct 25, 2024

It looks like w3c/accname#205 is a blocker here. The accname 1.2 spec, current browser implementations, the current visible label rule, and this PR all disagree on where to add whitespace.

It's difficult to be sure whether this PR makes false positives better or worse without a lot more examples.

Here are some test cases:

        <!-- Example 1 - Passes current rule and PR 2075
         accname-1.2: One
         Chrome 129 accname: One
         FF 131 accname: One
         Safari 17.6 accname: One
         visible text content (current rule): One
         visible text content (PR 2075): One
         -->
        <button>One</button>

        <!-- Example 2 - fails current rule and PR 2075 because accname computed per spec has a space that visible text content doesn't
         accname-1.2: One Two
         Chrome 129 accname: OneTwo
         FF 131 accname: OneTwo
         Safari 17.6 accname: One Two (Note: Safari 17 accname has a space, Chrome/FF doesn't add a space)
         visible text content (current rule): OneTwo
         visible text content (PR 2075): OneTwo

         see https://github.com/w3c/accname/issues/205
        -->
        <button><span>One</span><span>Two</span></button>

        <!-- Example 3 - Passes current rule and PR 2075
         accname-1.2: One Two
         Chrome 129 accname: One Two
         FF 131 accname: One Two
         Safari 17.6 accname: One Two
         visible text content (current rule): One Two
         visible text content (PR 2075): One Two
        -->
        <button><span>One</span> <span>Two</span></button>

        <!-- Example 4 - Passes current rule and PR 2075
         accname-1.2: One Two
         Chrome 129 accname: One\nTwo
         FF 131 accname: One Two
         Safari 17.6 accname: One Two
         visible text content (current rule): One Two
         visible text content (PR 2075): One Two
        -->
        <button><span>One</span><br><span>Two</span></button>

        <!-- Example 5 - Fails current rule and passes with PR 2075
         accname-1.2: One Two
         Chrome 129 accname: One Two
         FF 131 accname: One Two
         Safari 17.6 accname: One Two
         visible text content (current rule): OneTwo
         visible text content (PR 2075): One\nTwo\n
        -->
        <button><div>One</div><div>Two</div></button>

@Jym77
Copy link
Collaborator

Jym77 commented Oct 25, 2024

@dd8 From these five examples, it seems that:

  • this PR improves some without making anything worse, so it probably goes in the wrong direction anyway;
  • the weird case that this PR doesn't handle is also something that accname is fighting with, so we probably won't solve it on our own.

Based on that, I feel that we could indeed move on with this PR, it is a step in the good direction. Worst case is that when we come up with the perfect solution we'll throw away everything from here, but in the meantime we are still in a slightly better place.

I agree we should probably take up the discussion with the rest of the CG anyway.

@dd8
Copy link
Collaborator

dd8 commented Oct 25, 2024

I think the whitespace handling in the different algorithms can be summarised like so:

  • accname-1.2 always adds a space between nodes
  • browser accname implementations usually add a space between nodes (space added for all display values except display:inline in Chrome/FF, space always added in Safari)
  • visible inner text used by this PR sometimes adds a space between nodes (space added for display:block display:table-caption display:table-cell display:table-row)
  • visible text content used by the previous version of this rule never adds a space between nodes

@dan-tripp-siteimprove Is my summary of visible inner text and visible text content correct?

@dan-tripp-siteimprove
Copy link
Collaborator Author

@dan-tripp-siteimprove Is my summary of visible inner text and visible text content correct?

Yes, I think so.

@dan-tripp-siteimprove
Copy link
Collaborator Author

@kengdoj On the call today I said that I had reduced the number of passed/failed examples in this PR. It turns out that was wishful thinking at best, because a minute ago I checked, and I see that this this PR currently has 16 Passed Examples and 18 Failed Examples. This rule as it is currently published has 6 and 5 respectively. I don't know what it should be, but that's what it currently is.

@dan-tripp-siteimprove
Copy link
Collaborator Author

The current record holders are Content has alternative for visual reference with 15 passed examples and Text has enhanced contrast with 13 failed examples.

@dan-tripp-siteimprove
Copy link
Collaborator Author

@shunguoy in the examples for this PR, there are buttons with inner text in passed example 4, passed example 7, failed example 10 and failed example 11 - are these the kind of examples you're interested in?

@shunguoy
Copy link

shunguoy commented Jan 24, 2025 via email

@dan-tripp-siteimprove
Copy link
Collaborator Author

Thank you for clarifying. I hadn't thought of <label> cases before, and I don't know of any <label> cases - as they relate to the 'label in name' SC - being covered by other ACT rules.

This rule is interested in two pieces of information: the visible label and the accessible name. Your cases seem to raise questions about the visible label i.e. whether this rule should consider <label> element contents to be part of the visible label. Your cases seem not to raise any questions about the accessible name. For the accessible name, we at ACT use the accessible name computation algorithm, which is defined by another group of people, and which seems to work fine. The complications we have seem to all be regarding the "visible label" part of this. Am I right?

The 'label in name' SC mentions <label> only briefly, and not in a way that helps us, as far as I can tell. If anything, it suggests that we need to be concerned with <label> cases, and much more: ""label" is not used in such a programmatic sense but is simply referring to a text string in close visual proximity to a component".

This is a worthwhile issue, but probably not something that this PR can fix. If you would like to collaborate with me on a future PR, let me know.

@Jym77
Copy link
Collaborator

Jym77 commented Jan 27, 2025

@shunguoy This is a good point indeed.

I think the rule tried to deflect the problem by restricting its Applicability to roles that accept name from content (thus, e.g., dodging <input> textboxes and most labelable elements), but then at least (native) buttons, radio buttons and checkboxes are labelable and accept name from content. So we need to decide whether in this case the "visible label" is only the inner text (what the rule considers now), or also the associated label element.

The rule actually requires all of (i) name from content; (ii) (non-empty) visible inner text; and (iii) aria-label(edby). I think that in these cases, the likelihood of also having a label element is fairly low (i.e. very few authors would use your <label for=’abc’>Recording </label><button id=’abc’ aria-label=’recording the document’>Do it</button> example (this currently fails the rule)). But I've learnt that "nobody in their right mind would do that" is usually wrong when talking about HTML 🙈

As @dan-tripp-siteimprove says, this is unrelated to the current PR, but definitely worth discussing, can you open an issue so we don't forget about it?

@shunguoy
Copy link

shunguoy commented Jan 27, 2025

will do. Thanks.

#2236

Copy link
Collaborator

@sage-putnam sage-putnam left a comment

Choose a reason for hiding this comment

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

While I think the comment for improving upon this work (concerns around parenthesis meaning different things within different contexts) is valid and should be addressed, I agree that it may be best to take it up as an improvement.

Aside from this, I believe the number of examples to be appropriate given the complexity of the rule, and everything else seems correct to my understanding. Approving!

@@ -135,7 +135,7 @@
- ozplayer
- GitHub

# Test case anamolies
# Test case anomolies
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
# Test case anomolies
# Test case anomalies


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

This rule assumes that for any word which appears in both the accessible name and the visible label, the same spelling and hyphenation is used in both places. For example: if "non-negative" is used in the accessible name and "nonnegative" is used in the visible label, that would violate this assumption. Or if "color" is used in the accessible name and "colour" is used in the visible label, that would also violate this assumption.
Copy link
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 assumes that for any word which appears in both the accessible name and the visible label, the same spelling and hyphenation is used in both places. For example: if "non-negative" is used in the accessible name and "nonnegative" is used in the visible label, that would violate this assumption. Or if "color" is used in the accessible name and "colour" is used in the visible label, that would also violate this assumption.
This rule assumes that for any word which appears in both the accessible name and the visible label, the same spelling and hyphenation is used in both places. For example, if "non-negative" is used in the accessible name and "nonnegative" is used in the visible label, that would violate this assumption. Similarly, if "color" is used in the accessible name and "colour" is used in the visible label, that would also violate this assumption.

- 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.)
- Remove all characters that are within parentheses (AKA round brackets).
Copy link
Collaborator

Choose a reason for hiding this comment

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

Given that we know this is an issue, I think it should be included some how as a note that it may result in false negatives in these situations. Particularly since we are already recognising i18n differences in the whitespace splitting part of this algorithm.

- It checks whether elements are consecutive or not. That is: it checks for a substring, in the computer science sense of the term. Not a subsequence.
- An empty list is a sublist of any list.

If the answer is "yes" (that is: the tokenized 'label' is a sublist of the tokenized 'name'), then this algorithm returns "is contained". Otherwise, it returns "is not contained".
Copy link
Collaborator

Choose a reason for hiding this comment

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

Daft question time. What if the label is 'This is a cat' and the name is 'This is not a cat'. The tokenized name would include the tokenized label but is obviously entirely incorrect.

I would be happy to be missing something in the specific definitions of 'is contained' and 'sublist'.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@iadawn when you wrote "these situations", which situation do you mean? Is it (a) (Judgment of "non-text")? If so: I think that would result in a false positive (i.e. incorrect failing of the rule), not a false negative.

As for the 'This is a cat' case: I tried to cover that with the bullet point that starts with "It checks whether elements are consecutive or not."

Copy link
Collaborator

Choose a reason for hiding this comment

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

'These situations' relates to the situation where removal of parenthesis results in a change in meaning for certain languages. You note that these will result in a false negative but it might be worth being clear about that possibility in the text somehow.

Regarding the cat and rereading it I think that the problem may start with the statement:

is the tokenized 'label' a sublist of the tokenized 'name'

That introduces the term 'sublist' - which has it's own particular meaning - and then defines that term in a different way to it's own particular meaning.

Perhaps another way to write this would be:

Suggested change
If the answer is "yes" (that is: the tokenized 'label' is a sublist of the tokenized 'name'), then this algorithm returns "is contained". Otherwise, it returns "is not contained".
Then check if the consecutive tokenized 'label' is contained within the tokenized 'name'.

Or some such.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

'These situations' relates to the situation where removal of parenthesis results in a change in meaning for certain languages.

@iadawn I see now. Thank you for clarifying. I just pushed two commits for it. Does that cover it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That introduces the term 'sublist' - which has it's own particular meaning - and then defines that term in a different way to it's own particular meaning.

You replaced "sublist" with "contained within". In all respect, I think that's a step backwards. "Contained within" is ambiguous, as was revealed by #1458 , which this PR (in it's current state i.e. using my definition of "sublist") fixes.

That introduces the term 'sublist' - which has it's own particular meaning - and then defines that term in a different way to it's own particular meaning.

I'm afraid I don't understand either part of that of that sentence. 1) Assuming that by "particular meaning" you mean "official definition": I couldn't find any official definition of "sublist", so I made my own. 2) Even if "sublist" had an official definition somewhere, I assume that official definition would define it to work the same as every programming language's "subList()" function, which means: consecutive elements, same order. Which is the same way that my definition works. So how my definition differs from that is beyond me.

Copy link

netlify bot commented Feb 18, 2025

Deploy Preview for act-rules ready!

Name Link
🔨 Latest commit f9850c8
🔍 Latest deploy log https://app.netlify.com/sites/act-rules/deploys/67bcc0c9a40c280008177f5b
😎 Deploy Preview https://deploy-preview-2075--act-rules.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@daniel-montalvo
Copy link
Collaborator

Hey @dan-tripp-siteimprove

I've resolved conflicts with the 'develop' branch. Some of them were tricky. Would appreciate if you can take a look to see if I messed up with something here.


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.

Sub-algorithm to tokenize a string:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Since these steps are sequential, suggest they be numbered instead of bullet points.

@dan-tripp-siteimprove
Copy link
Collaborator Author

Hey @dan-tripp-siteimprove

I've resolved conflicts with the 'develop' branch. Some of them were tricky. Would appreciate if you can take a look to see if I messed up with something here.

Nice, thank you. I hadn't thought to do that. I will take a look - but it might take me a few days.

@dan-tripp-siteimprove
Copy link
Collaborator Author

Would appreciate if you can take a look to see if I messed up with something here.

@daniel-montalvo I looked today and I found no problems. Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
reviewers wanted Rule Update Use this label for an existing rule that is being updated
Projects
None yet
10 participants