-
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
Changes from all commits
cfb7ee6
e3277ac
34776c7
ea4a62f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,180 @@ | ||
| --- | ||
| id: 7ed469 | ||
| name: Element language is programmatically determinable | ||
| 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 | ||
| wcag20:3.1.2: # Language of Parts (AA) | ||
| forConformance: true | ||
| failed: not satisfied | ||
| passed: further testing is needed | ||
| inapplicable: further testing is needed | ||
| input_aspects: | ||
| - DOM Tree | ||
| - CSS Styling | ||
|
|
||
| acknowledgements: | ||
| authors: | ||
| - Patrick H. Lauke | ||
| --- | ||
|
|
||
| ## Applicability | ||
|
|
||
| This rules applies to any HTML element that: | ||
|
|
||
| * contains a [text node](https://dom.spec.whatwg.org/#text) as a [child](https://dom.spec.whatwg.org/#concept-tree-child) element | ||
| * is a [descendant](https://dom.spec.whatwg.org/#concept-tree-descendant) in the [flat tree](https://drafts.csswg.org/css-scoping/#flat-tree) of a `body` element | ||
| * is [included in the accessibility tree][] | ||
|
|
||
| ## Expectation (1) | ||
|
|
||
| For each test target, the test target itself or any of its [ancestor](https://dom.spec.whatwg.org/#concept-tree-ancestor) elements (up to and including the root element of the document) in the [flat tree](https://drafts.csswg.org/css-scoping/#flat-tree) has a `lang` attribute with a valid language subtag. | ||
|
|
||
| ## Assumptions | ||
|
|
||
| _There are currently no assumptions_ | ||
|
|
||
| ## Accessibility Support | ||
|
|
||
| _There are no major accessibility support issues known for this rule._ | ||
|
|
||
| ## Background | ||
|
|
||
| In practice, this rule will be satisfied if the separate success criterion [3.1.1 Language of Page (Level: A)](https://www.w3.org/TR/WCAG21/#language-of-page) is satisfied. This rule ensures that if 3.1.1 is *not* satisfied, content is checked for alternative ways in which language of page content itself can still have a programmatically determinable human language. | ||
|
|
||
| - [CSS Scoping Module Level 1 (editor's draft)](https://drafts.csswg.org/css-scoping/) | ||
| - [Understanding Success Criterion 3.1.2: Language of Parts](https://www.w3.org/WAI/WCAG21/Understanding/language-of-parts.html) | ||
|
|
||
| ## Test Cases | ||
|
|
||
| ### Passed | ||
|
|
||
| #### Passed Example 1 | ||
|
|
||
| The language of the `p` element is inherited by the `lang` attribute on the `html` root element. | ||
|
|
||
| ```html | ||
| <html lang="en"> | ||
| <body> | ||
| <p>Content</p> | ||
| </body> | ||
| </html> | ||
| ``` | ||
|
|
||
| #### 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> | ||
| ``` | ||
|
Comment on lines
+65
to
+93
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These two examples are actually pretty much the same (the 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
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
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.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
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
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note that you can also go even simpler: 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…
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 :) |
||
|
|
||
| ### Failed | ||
patrickhlauke marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| #### Failed Example 1 | ||
|
|
||
| The language of the `p` element cannot be programmatically determined as the element itself and none of its ancestors, including the `html` root element, has a defined `lang` attribute. | ||
|
|
||
| ```html | ||
| <html> | ||
| <body> | ||
| <p>Content</p> | ||
| </body> | ||
| </html> | ||
| ``` | ||
|
|
||
| #### Failed Example 2 | ||
|
|
||
| The language of the `p` element with `id` attribute `ko` cannot be programmatically determined as the element itself and none of its ancestors, including the `html` root element, has a defined `lang` attribute. | ||
|
|
||
| ```html | ||
| <html> | ||
| <body> | ||
| <div lang="en"> | ||
| <div> | ||
| <p id="ok">Content</p> | ||
| </div> | ||
| </div> | ||
| <div> | ||
| <p id="ko">Content</p> | ||
| </div> | ||
| </body> | ||
| </html> | ||
| ``` | ||
|
|
||
| #### Failed Example 3 | ||
|
|
||
| The language of the `p` element is inherited by the `lang` attribute on the `div` ancestor element, but the value of this `lang` attribute is not a valid language subtag. | ||
|
|
||
| ```html | ||
| <html> | ||
| <body> | ||
| <div lang="foo"> | ||
| <div> | ||
| <p>Content</p> | ||
| </div> | ||
| </div> | ||
| </body> | ||
| </html> | ||
| ``` | ||
|
|
||
| ### Inapplicable | ||
patrickhlauke marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| #### Inapplicable Example 1 | ||
|
|
||
| While the language of the `p` element cannot be programmatically determined, as the element itself and none of its ancestors has a defined `lang` attribute, the `p` element contains no actual text content. | ||
|
|
||
| ```html | ||
| <html> | ||
| <body> | ||
| <p></p> | ||
| </body> | ||
| </html> | ||
| ``` | ||
|
|
||
| #### Inapplicable Example 2 | ||
|
|
||
| While the language of the `p` element cannot be programmatically determined, as the element itself and none of its ancestors has a defined `lang` attribute, the `p` element is not part of the accessibilty tree. | ||
|
|
||
| ```html | ||
| <html> | ||
| <body> | ||
| <p aria-hidden="true">Content</p> | ||
| </body> | ||
| </html> | ||
| ``` | ||
|
|
||
| #### Inapplicable Example 2 | ||
patrickhlauke marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| The `body` element has no descendants. | ||
|
|
||
| ```html | ||
| <html> | ||
| <body></body> | ||
| </html> | ||
| ``` | ||
|
|
||
| [included in the accessibility tree]: #included-in-the-accessibility-tree 'Definition of included in the accessibility tree' | ||
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 validlang.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_requirementsas the list of (in this case) WCAG SCs that this is used to test conformance to. as this rule is scoped to descendants ofbody, it cannot be used to test 3.1.1 language of the page itself, as that needs to (in HTML) be defined for thehtmlelement?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
where the
pfails because its ancestordivhas 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.1There 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 validlangtag.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
langattribute" 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
bodyhas validlangattribute, 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.