diff --git a/__tests__/spelling-ignore.yml b/__tests__/spelling-ignore.yml index 299bc0f8b9d..bf174d33523 100755 --- a/__tests__/spelling-ignore.yml +++ b/__tests__/spelling-ignore.yml @@ -163,6 +163,7 @@ - innerText - isTrusted - isComposing +- onclick # DOM Events - auxclick @@ -251,3 +252,8 @@ # Language codes - da - nl + +# Color names +- 0000EE +- 551A8B +- EFEFEF diff --git a/_rules/text-contrast-afw4f7.md b/_rules/text-contrast-afw4f7.md index 0d91eb3a768..14f5de74c46 100755 --- a/_rules/text-contrast-afw4f7.md +++ b/_rules/text-contrast-afw4f7.md @@ -3,7 +3,7 @@ id: afw4f7 name: Text has minimum contrast rule_type: atomic description: | - This rule checks that the highest possible contrast of every text character with its background meets the minimal contrast requirement. + This rule checks that, for text which is not inside a widget, the highest possible contrast of every text character with its background meets the minimal contrast requirement. accessibility_requirements: wcag20:1.4.3: # Contrast (Minimum) forConformance: true @@ -61,6 +61,7 @@ This rule is designed specifically for [1.4.3 Contrast (Minimum)][sc143], which When the text color or background color is not specified in the web page, colors from other [origins][] will be used. Testers must ensure colors are not affected by styles from a [user origin][], such as a custom style sheet. Contrast issues caused by specifying the text color but not the background or vice versa, must be tested separately from this rule. +- [Text inside widget has minimum contrast](https://act-rules.github.io/rules/nqzcj8) - [Understanding Success Criterion 1.4.3: Contrast (Minimum)](https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html) - [Understanding Success Criterion 1.4.6: Contrast (Enhanced)](https://www.w3.org/WAI/WCAG21/Understanding/contrast-enhanced.html) - [G18: Ensuring that a contrast ratio of at least 4.5:1 exists between text (and images of text) and background behind the text](https://www.w3.org/WAI/WCAG21/Techniques/general/G18) diff --git a/_rules/text-contrast-widget-nqzcj8.md b/_rules/text-contrast-widget-nqzcj8.md new file mode 100755 index 00000000000..879be359f36 --- /dev/null +++ b/_rules/text-contrast-widget-nqzcj8.md @@ -0,0 +1,505 @@ +--- +id: nqzcj8 +name: Text inside widget has minimum contrast +rule_type: atomic +description: | + This rule checks that, for text in widgets, the highest possible contrast of every text character with its background meets the minimal contrast requirement. +accessibility_requirements: + wcag20:1.4.3: # Contrast (Minimum) + forConformance: true + failed: not satisfied + passed: further testing needed + inapplicable: further testing needed + wcag20:1.4.6: # Contrast (Enhanced) + forConformance: true + failed: not satisfied + passed: further testing needed + inapplicable: further testing needed +input_aspects: + - Accessibility Tree + - DOM Tree + - CSS Styling + - Language +acknowledgments: + authors: + - Jean-Yves Moyen +--- + +## Applicability + +This rule applies to a [visible][] character in a [text node][] for which all the following are true: + +- **widget** the [text node][] has an [ancestor][] in the [flat tree][] with a [semantic role][] that inherit from `widget`; and +- **enabled** the closest [ancestor][] of the [text node][] in the [flat tree][] with a [semantic role][] of `widget` is not [disabled][]. + +### Applicable States + +This rule applies whenever the closest [ancestor][] of the [text node][] in the [flat tree][] is in any state [def needed, intention here is "set of CSS pseudo classes matched by an element"] that contains neither `:active` nor `:hover`. + +## Expectation + +For each test target, the [highest possible contrast][] between its [foreground colors][] and [background colors][] is at least 4.5:1 or 3.0:1 for [larger scale text][], except if the test target is part of a [text node][] that is [purely decorative][] or does not express anything in [human language][]. + +## Assumptions + +- [Success criterion 1.4.3: Contrast (Minimum)][sc143] and [Success criterion 1.4.6: Contrast (Enhanced)][sc146] have exceptions for "incidental" text, which includes inactive user interface components and decorative texts. The rule assumes that [text nodes][text node] that should be ignored are [disabled][] or hidden from assistive technologies. If this isn't the case, the text node could fail this rule while the success criteria could still be satisfied. + +- [Success criterion 1.4.3: Contrast (Minimum)][sc143] and [Success criterion 1.4.6: Contrast (Enhanced)][sc146] also have an exception for logos and brand names. Since logos and brand names are usually displayed through images to ensure correct rendering, this rule does not take logos or brand names into consideration. If a logo or brand name is included using [text nodes][text node], the text node could fail while the success criteria could still be satisfied. + +- Text that has the same foreground and background color (a contrast ratio of 1:1) is not considered to be "visual presentation of text", making it inapplicable to the success criterion. Text hidden in this way can still cause accessibility issues under other success criteria, depending on the content. + +- The definition of [disabled element][disabled] assumes that when the `aria-disabled` attribute is specified on an element, this element has also been disabled for users that do not rely on [assistive technology][]. If this is not the case, that definition may produce incorrect results and in consequence this rule might be Inapplicable to some text nodes that still require a good contrast ratio. + +- This rule considers that `:hover` and especially `:active` are transient states and therefore a poor color contrast during the short time when they are matched is not causing any issue. Therefore, the rule does not check widgets in these states. If these states still require a high contrast ratio, it is possible to pass still rule while still failing [Success criterion 1.4.3: Contrast (Minimum)][sc143] and [Success criterion 1.4.6: Contrast (Enhanced)][sc146]. + +- This rule only checks the various appearances of widgets that correspond to states [def needed]. Scripting can result in changes of appearance after interaction that are not reflected that way. For example, a `onclick` function could change the CSS classes on an element and thus result in changing the text colors. This rule does not check these and thus can pass while still failing [Success criterion 1.4.3: Contrast (Minimum)][sc143] and [Success criterion 1.4.6: Contrast (Enhanced)][sc146]. Such interactions must be tested separately. + +## Accessibility Support + +- Different browsers have different levels of support for CSS. This can cause contrast issues in one browser that do not appear in another. Because of that, this rule can produce different results depending on the browser that is used. For example, a text that is positioned using CSS transform may be on a different background in a browser that does not support CSS transform. +- Implementation of [Presentational Roles Conflict Resolution][] varies from one browser or assistive technology to another. Depending on this, some elements can have a [semantic role][] inheriting from `widget` and fail this rule with some technology but users of other technologies would not experience any accessibility issue. + +## Background + +The **enabled** condition effectively prevents `:disabled` to be in the state [def needed]. + +The CSS pseudo-classes are naturally mapped to the native "HTML widgets" (elements whose [implicit role][] inherits from `widget`) depending on the state of the page and according to the [HTML pseudo-classes][]. On the other hand, "ARIA widgets" (elements whose [implicit role][] does not inherit from `widget`, but with an [explicit role][]) normally can't match most pseudo-classes. For example, an HTML link (such as an `a` element with an `href` attribute) will always match either the `:link` or `:visited` [widget pseudo-class][], but an ARIA link (such as a ``) will never match any of these. This is a consequence of ARIA's [Non-interference with the Host Language][]. ARIA widgets are nonetheless considered by this rule with an empty state, and sometimes also with `:focus` if the element has been made [focusable][]. + +Passing this rule does not mean that the text has sufficient color contrast. If all background pixels have a low contrast with all foreground pixels, the success criterion is guaranteed to not be satisfied. When some pixels have sufficient contrast, and others do not, legibility should be considered. There is no clear method for determining legibility, which is why this is out of scope for this rule. + +When the text color or background color is not specified in the web page, colors from other [origins][] will be used. Testers must ensure colors are not affected by styles from a [user origin][], such as a custom style sheet. Contrast issues caused by specifying the text color but not the background or vise versa, must be tested separately from this rule. + +- [Text has minimum contrast](https://act-rules.github.io/rules/afw4f7) +- [Understanding Success Criterion 1.4.3: Contrast (Minimum)](https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html) +- [Understanding Success Criterion 1.4.6: Contrast (Enhanced)](https://www.w3.org/WAI/WCAG21/Understanding/contrast-enhanced.html) +- [G18: Ensuring that a contrast ratio of at least 4.5:1 exists between text (and images of text) and background behind the text](https://www.w3.org/WAI/WCAG21/Techniques/general/G18) +- [G145: Ensuring that a contrast ratio of at least 3:1 exists between text (and images of text) and background behind the text](https://www.w3.org/WAI/WCAG21/Techniques/general/G145) +- [F83: Failure of Success Criterion 1.4.3 and 1.4.6 due to using background images that do not provide sufficient contrast with foreground text (or images of text)](https://www.w3.org/WAI/WCAG21/Techniques/failures/F83) +- [CSS Scoping Module Level 1 (Editor's Draft)](https://drafts.csswg.org/css-scoping/) + +Due to the various [widget pseudo-classes][] that a given element can match, each example often contains several test targets. For example, a link is applicable with the sets of [widget pseudo-classes][] {`:link`}, {`:link`, `:focus`}, {`:visited`}, and {`:visited`, `:focus`}. Test case descriptions often do not list all of these, unless the example illustrates something about them. + +## Test Cases + +### Passed + +#### Passed Example 1 + +With default browser styling, the text in this `a` element with an [implicit role][] of `link` has a white background and is blue (`#0000EE`) thus it has a contrast ratio of 9.4:1. + +```html +ACT rules +``` + +#### Passed Example 2 + +With default browser styling, the text in the `span` element inside this link has contrast ratio of 9.4:1 when the `a` element matches `:link`, and 11:1 when it matches `:visited`. The text is not a child of the widget, but is nonetheless a descendant of it. + +```html +ACT rules +``` + +#### Passed Example 3 + +With default browser styling, the text in this `button` element has a light gray background (`#EFEFEF`) and black text, resulting in a 18.3:1 contrast ratio. + +```html + +``` + +#### Passed Example 4 + +With default browser styling, the text in this focused `a` element with an [implicit role][] of `link` has a white background and is blue (`#0000EE`), thus it has a contrast ratio of 9.4:1. + +```html + + + + ACT rules + + +``` + +#### Passed Example 5 + +With default browser styling, the text in this visited `a` element with an [implicit role][] of `link` has a white background and is purple (`#551A8B`), thus it has a contrast ratio of 11:1. + +```html + + + + ACT rules + + +``` + +#### Passed Example 6 + +With default browser styling, the text in this visited and focused `a` element with an [implicit role][] of `link` has a white background and is purple (`#551A8B`), thus it has a contrast ratio 11:1. + +```html + + + + ACT rules + + +``` + +#### Passed Example 7 + +TODO: split into 4 examples as 1/4/5/6? + +The text in this link, on default white background, has color contrast ratios of 8.6:1, 10:1, 5.1:1, and 5.2:1 in the 4 states listed in the `style` element. + +```html + +ACT rules +``` + +#### Passed Example 8 + +The text in this `input` element, on default white background, has color contrast ratios of 5.1:1, and 8.6:1 when it's focused or not. Note that in modern browsers, the text itself is included in a shadow tree inside the `input` element. + +```html + + +``` + +#### Passed Example 6 + +The text in this `input` element, on default white background, has color contrast ratios of 5.1:1, and 10:1 when it's focused or not. Note that when the `input` element is matching both the `:placeholder-shown` and the `:focus` [widget pseudo-classes][], the styling defined latest takes precedence. The text keeps a color ratio of 8.6:1 if some value is provided. + +```html + + +``` + +#### Passed Example 7 + +With default browser styling, the text in this link, has a white background and is blue (`#0000EE`) when matching `:link` and purple (`#551A8B`) when matching `:visited`. These colors have a respective contrast ratios of 9.4:1 and 11:1 with the white background. When the link matches both `:link` and `:active`, the contrast ratio of its text is only 2:1, however, the `:active` [widget pseudo-class][] is ignored by this rule. + +```html + +ACT rules +``` + +#### Passed Example 8 + +The dark gray text in this `span` element with an [explicit role][] of `link` has a color contrast ratio of 12.6:1 on the white background. Note that it cannot match any of the [widget pseudo-classes][] and is thus only applicable with the empty set of such pseudo-classes. + +```html + + Some text in a human language + +``` + +#### Passed Example 9 + +The dark gray text in this `span` element with an [explicit role][] of `link` has a color contrast ratio of 12.6:1 on the white background. Note that it can only match the `:focus` [widget pseudo-class][] and is thus only applicable with the empty set and with the singleton set {`:focus`}. + +```html + + Some text in a human language + +``` + +#### Passed Example 10 + +The dark gray text in this link has a contrast ratio between 12.6:1 and 9.5:1 on the white to blue gradient background. + +```html +

+ ACT rules +

+``` + +#### Passed Example 11 + +This light gray text in this link has a contrast ratio between 13:1 and 5:1 on the background image. + +```html +

+ ACT rules +

+``` + +#### Passed Example 12 + +The 18pt large black text in this link has a contrast ratio of 3.6:1 on the gray background. + +```html +ACT rules +``` + +#### Passed Example 13 + +The 14pt bold black text in this link has a contrast ratio of 3.6:1 on the gray background. + +```html +ACT rules +``` + +#### Passed Example 14 + +The text in this `button` element does not convey anything in human language. + +```html + +``` + +### Failed + +#### Failed Example 1 + +The text in this link has a contrast ratio of 3.6:1. + +```html +ACT rules +``` + +#### Failed Example 2 + +The text in this button has a contrast ratio of 3.6:1. + +```html + +``` + +#### Failed Example 3 + +The text in this link, on default white background, has color contrast ratios of 1.5:1, 4:1, 1.3:1, and 2:1 in the 4 states listed in the `style` element. + +```html + +ACT rules +``` + +#### Failed Example 4 + +With default browser styling, the text in this link, has a white background and is blue (`#0000EE`) when matching `:link` and purple (`#551A8B`) when matching `:visited`. These colors have a respective contrast ratios of 9.4:1 and 11:1 with the white background. However, when the link matches both `:visited` and `:focus`, it only has a color contrast ratio of 2:1. + +```html + +ACT rules +``` + +#### Failed Example 5 + +The text in this `input` element, on default white background, has color contrast ratios of 2:1, and 1.5:1 when it's focused or not. + +```html + + +``` + +#### Failed Example 6 + +The placeholder text in this `input` element, on default white background, has color contrast ratios of 5.1:1, and 10:1 when it's focused or not. However, when text is entered and the placeholder is not shown, the text has only a 1.5:1 color contrast ratio. + +```html + + +``` + +#### Failed Example 7 + +The light gray text in this `span` element with an [explicit role][] of `link` has a color contrast ratio of 2.3:1 on the white background. + +```html + + Some text in a human language + +``` + +#### Failed Example 8 + +The light gray text in this link has a contrast ratio between 1.6:1 and 1.2:1 on the white to blue gradient background. + +```html +

+ ACT rules +

+``` + +### Inapplicable + +#### Inapplicable Example 1 + +There is no HTML element. + +```html + + ACT rules + +``` + +#### Inapplicable Example 2 + +There is no text which is part of a [text node][]. + +```html + + ACT rule + +``` + +#### Inapplicable Example 3 + +There is no [text node][] with a widget as an [ancestor]. + +```html +

I love ACT rules!

+``` + +#### Inapplicable Example 4 + +The text in this link is not [visible][] because of `display: none`. + +```html +ACT rules +``` + +#### Inapplicable Example 5 + +The text in this link is not [visible][] because it is positioned off-screen. + +```html +ACT rules +``` + +#### Inapplicable Example 6 + +The text in this link is not [visible][] because the foreground color is the same as the background color. + +```html +ACT rules +``` + +#### Inapplicable Example 7 + +This text is in a [disabled][] widget. + +```html + +``` + +[ancestor]: https://dom.spec.whatwg.org/#concept-shadow-including-ancestor 'DOM specification of Ancestor' +[assistive technology]: https://www.w3.org/TR/WCAG21/#dfn-assistive-technologies 'WCAG definition of Assistive Technologies' +[background colors]: #background-colors-of-text 'Definition of Background Color of Text' +[disabled]: #disabled-element 'Definition of Disabled' +[explicit role]: #explicit-role 'Definition of Explicit Semantic Role' +[flat tree]: https://drafts.csswg.org/css-scoping/#flat-tree "CSS definition of flat tree (editor's draft)" +[focusable]: #focusable 'Definition of Focusable' +[foreground colors]: #foreground-colors-of-text 'Definition of Foreground Color of Text' +[highest possible contrast]: #highest-possible-contrast 'Definition of Highest Possible Contrast' +[html pseudo-classes]: https://html.spec.whatwg.org/multipage/semantics-other.html#pseudo-classes 'HTML mapping of CSS selectors' +[human language]: https://www.w3.org/TR/WCAG21/#dfn-human-language-s 'WCAG 2.1 definition of Human language' +[implicit role]: #implicit-role 'Definition of Implicit Semantic Role' +[larger scale text]: #large-scale-text 'Definition of Large Scale Text' +[non-interference with the host language]: https://www.w3.org/TR/wai-aria-1.1/#ua_noninterference 'ARIA Non-interference with the Host Language' +[origins]: https://www.w3.org/TR/css3-cascade/#cascading-origins 'CSS definition of Origin' +[presentational roles conflict resolution]: https://www.w3.org/TR/wai-aria-1.1/#conflict_resolution_presentation_none 'WAI-ARIA definition of the Presentational Roles Conflict Resolution' +[purely decorative]: https://www.w3.org/TR/WCAG21/#dfn-pure-decoration 'WCAG 2.1 definition of Purely decorative' +[text node]: https://dom.spec.whatwg.org/#text 'DOM specification of text node' +[sc143]: https://www.w3.org/TR/WCAG21/#contrast-minimum 'WCAG 2.1, Success criterion 1.4.3 Contrast (Minimum)' +[sc146]: https://www.w3.org/TR/WCAG21/#contrast-enhanced 'WCAG 2.1, Success criterion 1.4.6 Contrast (Enhanced)' +[semantic role]: #semantic-role 'Definition of Semantic Role' +[user origin]: https://www.w3.org/TR/css3-cascade/#cascade-origin-user 'CSS definition of User Origin' +[visible]: #visible 'Definition of Visible' +[widget pseudo-class]: #widget-pseudo-classes 'Definition of Widget Pseudo-Classes' +[widget pseudo-classes]: #widget-pseudo-classes 'Definition of Widget Pseudo-Classes' diff --git a/pages/glossary/widget-pseudo-classes.md b/pages/glossary/widget-pseudo-classes.md new file mode 100755 index 00000000000..7b9b204241f --- /dev/null +++ b/pages/glossary/widget-pseudo-classes.md @@ -0,0 +1,14 @@ +--- +title: Widget Pseudo Classes +key: widget-pseudo-classes +unambiguous: true +objective: true +input_aspects: +--- + +The _Widgets Pseudo-Classes_ are the following [CSS selectors][]: `:link`, `:visited`, `:active`, `:hover`, `:focus`, `:enabled`, `:disabled`, `:checked`, `:indeterminate`, `:default`, `:placeholder-shown`, `:valid`, `:invalid`, `:in-range`, `:out-of-range`, `:required`, `:optional`, `:read-write`. + +These selectors are mapped to HTML elements according to the [HTML pseudo-classes][]. + +[css selectors]: https://drafts.csswg.org/selectors/ "CSS Selectors, Level 4, Editor's Draft" +[html pseudo-classes]: https://html.spec.whatwg.org/multipage/semantics-other.html#pseudo-classes 'HTML mapping of CSS selectors'