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

fix(link-in-text-block): Update rule to match current guidance, revise tests #3575

Merged
merged 17 commits into from
Sep 13, 2022

Conversation

DaveTryon
Copy link
Contributor

@DaveTryon DaveTryon commented Jul 28, 2022

This PR updates the link-in-text-block rule as described in #2817. The new rule converts a single check into 2 checks (link-in-text-block-style and link-in-text-block), as suggested. We use any, so the rule passes if either rule passes.

link-in-text-block-style check:

  • return false if the link is not actually a link (unchanged from before)
  • return true if the link and the containing text block have visually distinct styling independent of color

link-in-text-block check:

  • return false if the link is not actually a link (unchanged from before)
  • return true if either the foreground contrast ratio or the background contrast ratio is at least 3.0
  • return undefined if we couldn't get enough data to make a good decision. Possible values of messageKey:
    • default if we fail to obtain the foreground color of either the link or the containing text block
    • bgContrast if we fail to obtain background colors of either the link or the containing text block and no value for bgColor was set via incompleteData
    • bgImage, bgGradient, imgNode, or bgOverlap if a value for bgColor was set via incompleteData when trying to obtain a background color
  • return false with an appropriate value for messageKey:
    • bgContrast if the foreground color is unchanged and the background color changed
    • fgContrast if the foreground color has changed or if the background color is unchanged

Strings in the json file have been updated to include more information about the colors that were used to compute the ratios. Unit tests and integration tests have been updated (and slightly regrouped) to pin the updated behavior.

This covers the rule changes for #2817, but it leaves the rule categorized as experimental. Changing the rule category will need a separate change.

@DaveTryon DaveTryon requested a review from a team as a code owner July 28, 2022 17:29
@straker
Copy link
Contributor

straker commented Jul 28, 2022

Thanks for the pr! We'll need @WilcoFiers to look over it, which may take awhile as he is out.

Copy link
Contributor

@WilcoFiers WilcoFiers left a comment

Choose a reason for hiding this comment

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

We'll need integration tests for this.

lib/checks/color/link-in-text-block-evaluate.js Outdated Show resolved Hide resolved
lib/checks/color/link-in-text-block-evaluate.js Outdated Show resolved Hide resolved
lib/checks/color/link-in-text-block.json Outdated Show resolved Hide resolved
Comment on lines 75 to 76
// Message reflects the highest contrast ratio since it's the smallest fix
if (textContrast >= backgroundContrast) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I see where you're coming from, but I feel this may not be the right direction. For a link with 1. no underline, and 2. bad contrast, this is going to end up telling it to improve the contrast. I think what might be better is that we pull the contrast testing into a separate check, and make those "any" checks, so we can report it like so:

Fix one of the following:

  • The link has has no styling (such as underline) to distinguish it from the surrounding text
  • The link text insufficient contrast of 2:1 with the surrounding text. (Minimum contrast 3:1, link text: #ABC123, surrounding text: #CDE234)

For the background, I think that can be combined with the text color check. People don't use backgrounds on inline links all too often, we don't have to explicitly call it out unless there is a background on the link IMO.

Alternatively, we could do the background and foreground thing in the same check, and report whichever has the highest number like you're doing here. Changing background colors on inline links is rare, so it may not be necessary to point that option out unless someone is already using this. Might help on performance a bit too.

Re performance; When splitting this check it'll be good to do some performance testing, make sure we don't significantly slow down this rule. Color contrast can be expensive after all. If it does slow down we'll probably have to look at doing some more caching / memoization.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Refactored to use any. I'll reach out to you offline for details on how you generally handle perf testing

@DaveTryon DaveTryon dismissed a stale review via 79b509f August 9, 2022 23:48
@WilcoFiers WilcoFiers self-requested a review August 10, 2022 15:19
@WilcoFiers
Copy link
Contributor

@DaveTryon Is this ready again?

"metadata": {
"impact": "serious",
"messages": {
"pass": "Links can be distinguished from surrounding text in some way other than by color",
"fail": "Links need to be distinguished from surrounding text in some way other than by color",
"fail": {
"fgContrast": "The link has insufficient color contrast of ${data.contrastRatio}:1 with the surrounding text. (Minimum contrast is ${data.requiredContrastRatio}:1, link text: ${data.nodeColor}, surrounding text: ${data.parentColor})",
Copy link
Contributor

Choose a reason for hiding this comment

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

A thought that just occurred to me is that these messages mention color contrast when what we're actually analyzing is relative luminance contrast. Worth capturing in the error message to avoid confusion?

Copy link
Contributor

Choose a reason for hiding this comment

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

Color contrast is a better known term here. It'll e better understood. It means more or less the same thing anyway.

@DaveTryon DaveTryon changed the title fix: Update link-in-text-block and associated unit tests fix(link-in-text-block): Update rule to match current guidance, revise tests Aug 10, 2022
Comment on lines 122 to 132
<p style="color: black; background-image: linear-gradient(red, yellow)">
paragraph of text (incomplete: link has insufficient text contrast and
paragraphs has a background gradient)
<a
style="text-decoration: none; color: black"
href="#"
id="incomplete-low-contrast-parent-has-gradient"
>
Link test</a
>
</p>
Copy link
Contributor Author

@DaveTryon DaveTryon Aug 10, 2022

Choose a reason for hiding this comment

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

@WilcoFiers, I added a local integration test for this where the linear-gradient style is on the link instead of the paragraph. The browser rendered it correctly, but the rule doesn't return undefined. Debugging showed that the call to elementHasImage is returning false. That seems strange to me, but I didn't try to fix it in this PR. Just for reference, here's the change that I made to this test:

<p style="color: black">
  paragraph of text (incomplete: link has insufficient text contrast and
  paragraphs has a background gradient)
  <a
    style="text-decoration: none; color: black; background-image: linear-gradient(red, yellow)"
    href="#"
    id="incomplete-low-contrast-link-has-gradient"
  >
    Link test</a
  >
</p>

@DaveTryon
Copy link
Contributor Author

@DaveTryon Is this ready again?

@WilcoFiers: Yes, please take another pass. I left a comment of some behavior that I didn't expect in the integration tests

@WilcoFiers WilcoFiers dismissed their stale review August 22, 2022 16:27

checking again

Copy link
Contributor

@WilcoFiers WilcoFiers left a comment

Choose a reason for hiding this comment

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

Looks great. Apologies for the delayed review. I've been kind of swamped by WCAG 2.2 / 3.0 work the last couple weeks. I think we're almost ready to merge this in.

"metadata": {
"impact": "serious",
"messages": {
"pass": "Links can be distinguished from surrounding text in some way other than by color",
"fail": "Links need to be distinguished from surrounding text in some way other than by color",
"fail": {
"fgContrast": "The link has insufficient color contrast of ${data.contrastRatio}:1 with the surrounding text. (Minimum contrast is ${data.requiredContrastRatio}:1, link text: ${data.nodeColor}, surrounding text: ${data.parentColor})",
Copy link
Contributor

Choose a reason for hiding this comment

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

Color contrast is a better known term here. It'll e better understood. It means more or less the same thing anyway.

Copy link
Contributor

@WilcoFiers WilcoFiers left a comment

Choose a reason for hiding this comment

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

Reviewed for security. Thanks @DaveTryon!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants