-
Notifications
You must be signed in to change notification settings - Fork 79
New Rule: Element language is programmatically determinable #1027
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
New Rule: Element language is programmatically determinable #1027
Conversation
This rule is primarily aimed at catching situations where 3.1.1 Language of Page fails, which also leads to automatically failing 3.1.2 (since if the language for the overall page cannot be programmatically determined, neither can the language for any text nodes in the page itself unless there's been some explicit language definition further down in the DOM tree) Closes #1009
|
(note that I made this contribution from my own fork, as I don't think I can just clone and add a new branch directly here? for that reason, I'm also unable to add a label/assign myself) |
|
I'll also add that this is my first stab at doing an ACT rule, so I expect that I made some fundamental logic/form errors... |
Jym77
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a good start 😄 Most of my comments are on global style issues and not on the logic of the rule…
Additional points:
- many links are missing. Notably, "included in the accessibility tree", "flat tree", all the Success Criteria, … Please add them all over the place. You can use "footnote style" reference of markdown for links that are used several time.
- Add the Understanding document to Background. Also add CSS scoping with the WiP mention given that you reference it (check what is done in other rules).
- Given that you work on the flat tree (which makes sense), you need to add example with shadow tree. Given the nature of the rule, probably something where the shadow tree + flattening is "moving" a
langattribute. Maybe something with a slot where the slotted element has nolangancestor in the light tree, but shadow tree manipulation put it under an element with alang(or the other way around). - Maybe having an example with an iframe to show that the rule stops at document boundaries.
- There can also be a failed example where one element is OK but another one is not. This illustrates that the SC fails if there is at least one failed outcome.
Good job!
| rule_type: atomic | ||
| description: | | ||
| This rule checks that the language of an element in the page body can be programmatically determined. | ||
| accessibility_requirements: # Remove whatever is not applicable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the rule is also mapping to 3.1.1: if an element has no ancestor with a valid lang, then the document element has no valid lang.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i understood accessibility_requirements as the list of (in this case) WCAG SCs that this is used to test conformance to. as this rule is scoped to descendants of body, it cannot be used to test 3.1.1 language of the page itself, as that needs to (in HTML) be defined for the html element?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that the rule is not designed to test SC 3.1.1, but it still does test a bit of it indirectly…
As always, we focus on the fail-on-fail relationship. A failure of this rule indicates a failure of SC 3.1.1 (in addition to 3.1.2). A Pass on this rule does not indicate a Pass of 3.1.1, but neither of 3.1.2… That's how it is for most rules.
Then, it is true also that a failure of this rule implies a failure of HTML page has lang attribute, and that is why it fails 3.1.1. That's also OK. This rule checks more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wondering now if another failure purely for this rule (which i've not added here, but can if it's deemed an actual failure) would be something like
<html lang="en">
<body>
<div lang="foo">
<p>Content</p>
</div>
</body>
</html>
where the p fails because its ancestor div has an invalid language attribute, but the page itself does pass 3.1.1...and so a failure of this rule does not indicate a failure of 3.1.1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rule currently does not fail that because "any of its [the p] ancestor" has a valid lang tag.
I agree that this is a failure of 3.1.2 but not of 3.1.1
I see 2 possibilities:
=> Change the rule to "its closest ancestor with a lang attribute" or something similar. This makes the rule more tricky. In this case, it would indeed not map to 3.1.1
=> Leave the rule as is. This keeps the rule simpler and more focused. This case is already handled by Element within body has valid lang attribute, so there is no real need to enforce it in this rule. The main "problem" with this solution is that Passed Examples must pass the SC, so we cannot use this as a Passed Example to illustrate the limitation of the rule. This is not really a big deal…
Given that this case is already handle by anther rule, I'd rather keep this rule simple.
|
Just on this point
doesn't the rule get applied to every single element separately, in isolation? Don't quite understand therefore why there should be an example with two separate elements, as they'd be tested individually? |
|
Yes, the rule is applied to every element. <body>
<p lang="en" id="ok">Hello</p>
<p id="ko">World</p>
</body>the |
|
Also, I forgot to mention that you need to add yourself as "contributor" in |
- add relevant links and background references - remove redundant `style="display:none"` inapplicable example - add failed example with invalid language subtag - add failed example which includes another passing element - remove note about examples also failing 3.1.1 - more specifically scope applicability to elements that have text nodes as child elements - make the description for examples slightly less robotic sounding "Language" > "The language"
Done 1, 2 and 5. Have to admit that for 3 I have no idea what that even means, and 4 not quite sure how that would be shown/expressed in a code sample. Any hints for those two would be appreciated. |
From the top of my head… <html>
<body>
<div lang="en">Hello
<iframe srcdoc="<body><div>World</div></body>" />
</div>
</body>
</html>The For the shadow tree, … hmmm… <html>
<body>
<div id="host">
<span>Hello world</span>
</div>
<script>
const host = document.getElementById('host')
const shadowRoot = host.attachShadow({ mode: 'open' })
shadowRoot.innerHTML =
'<div lang="en"><slot></slot></div>'
</script>
</body><html>In the flat tree, the If you use instead |
| rule_type: atomic | ||
| description: | | ||
| This rule checks that the language of an element in the page body can be programmatically determined. | ||
| accessibility_requirements: # Remove whatever is not applicable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rule currently does not fail that because "any of its [the p] ancestor" has a valid lang tag.
I agree that this is a failure of 3.1.2 but not of 3.1.1
I see 2 possibilities:
=> Change the rule to "its closest ancestor with a lang attribute" or something similar. This makes the rule more tricky. In this case, it would indeed not map to 3.1.1
=> Leave the rule as is. This keeps the rule simpler and more focused. This case is already handled by Element within body has valid lang attribute, so there is no real need to enforce it in this rule. The main "problem" with this solution is that Passed Examples must pass the SC, so we cannot use this as a Passed Example to illustrate the limitation of the rule. This is not really a big deal…
Given that this case is already handle by anther rule, I'd rather keep this rule simple.
| #### Passed Example 2 | ||
|
|
||
| The language of the `p` element is inherited by the `lang` attribute on the `div` parent element. Note that this example fails 3.1.1 Language of Page (Level: A) as the `html` root element lacks a `lang` attribute. | ||
|
|
||
| ```html | ||
| <html> | ||
| <body> | ||
| <div lang="en"> | ||
| <p>Content</p> | ||
| </div> | ||
| </body> | ||
| </html> | ||
| ``` | ||
|
|
||
| #### Passed Example 3 | ||
|
|
||
| The language of the `p` element is inherited by the `lang` attribute on the `div` ancestor element. Note that this example fails 3.1.1 Language of Page (Level: A) as the `html` root element lacks a `lang` attribute. | ||
|
|
||
| ```html | ||
| <html> | ||
| <body> | ||
| <div lang="en"> | ||
| <div> | ||
| <p>Content</p> | ||
| </div> | ||
| </div> | ||
| </body> | ||
| </html> | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These two examples are actually pretty much the same (the lang attribute is on an ancestor which is not the html element). You can remove one of them.
OTOH, I think it would be good to add an example to illustrate the "child text node" part of the rule.
<body>
<div>
<p lang="en">Hello</p>
</div>
</body>The p is good. The div is inapplicable. So this passes the rule.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change the rule to "its closest ancestor with a lang attribute" or something similar
I think I'm actually tending towards this one, as the closest ancestor is indeed what plays the major part in the essence of this rule, as it relates more closely in how the language of the specific element itself is calculated/programmatically determined.
And mainly, because I do think there's value in making sure that it's clear that there can be failures of this rule that fail 3.1.2 but not 3.1.1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These two examples are actually pretty much the same
ah, good spot. wanted to make the difference between parent and ancestor clear (or rather, that we're not just talking about parent), but probably no need to do two examples that are so close to each other. will go with ancestor one, as parent is just a special case of ancestor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that you can also go even simpler:
check the existence of a lang attribute, not its validity. Then you can go for any ancestor without problem, the rule is much simpler and keep a single concern (it does not need to know what are valid/invalid language tags). Given that we already have rules that check validity of language tags, this is not going to be a real problem.
The point here being that we don't need the rule to be completely covering a single SC. It is better (imho) to have simple rules checking a simple thing and use a combination of rules to cover a SC (rules are already complicated beast, keeping them simple helps writers, readers and testers; simpler rules are also better for separation of concern).
This is a personal opinion and mostly showing what can be done. Of course, go the direction you want 😄 given that you are the one doing the job in the first place…
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'll mull it over. appreciate the thorough discussion on this, particularly as i dove in on the deep end here :)
|
I'm going to close this as this PR has not been updated in 8 months. If someone wants to pick this up again, we can reopen the PR or create a new one. |
This rule is primarily aimed at catching situations where 3.1.1 Language of Page fails, which also leads to automatically failing 3.1.2 (since if the language for the overall page cannot be programmatically
determined, neither can the language for any text nodes in the page itself unless there's been some explicit language definition further down in the DOM tree)
Closes issue(s):
Need for Final Call:
This will require a 2 weeks Final Call
Pull Request Etiquette
When creating PR:
developbranch (left side).After creating PR:
Rule,DefinitionorChore.How to Review And Approve