axe-core: Pseudo element contrast failure too invasive?

👋

I’ve run into a situation where :nth-child style pseudo selectors are wrongly being identified as pseudo elements and therefore, can’t assume contrast acceptance. I’ve tracked down to this section here, but it does seem to only be checking for :before and :afters. Maybe something in the function being called?

https://github.com/dequelabs/axe-core/blob/f2f15377c917d0b6fc27d2181f64ebef26e5a9b0/lib/checks/color/color-contrast-evaluate.js#L103-L116

Anyhow, here’s also a screenshot showing the run through using the Chrome plugin and the result: Screen Shot 2021-01-26 at 14 25 39 PM

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 1
  • Comments: 20 (9 by maintainers)

Most upvoted comments

Ok. We added the option and it should be available in the next feature release (coming in the next few weeks hopefully). Do note though that turning off the option may result in a Needs Review item being marked as a failure, so you’ll need to watch out to see what it will change for your tests.

@craigkovatch the UI changes wouldn’t affect the js library. We’ll add an option to disable the pseudo check of color-contrast so you can turn off these warnings if you want.

@clottman for this one, let’s check in the pseudo algorithm the display and visibility of the element, if it’s none or hidden (respectively) we shouldn’t flag it as having a pseudo element. Additionally, let’s add an option to disable the pseudo check entirely. Let’s call it ignorePseudo to match the other options we have, and set it to default to false.

@straker I would like to register again the strong objection to the false negatives that this approach generates. We use pseudo elements to render custom images for styled checkbox and radio inputs, which is fairly common practice across the web (see my screenshot in previous comment). Since upgrading our Axe version, we are now getting a plethora of these false failures. This is causing many hours of wasted engineering effort by those who are unaware that the failures should be ignored. Please reconsider this change, or offer a much more robust way of skipping/disabling it. It’s bad enough that I’m recommending we (Tableau) actually roll back our version of Axe to avoid these failures.

@craigkovatch We’ve thought about doing the math, but I’m afraid that would cause more issues than just flagging the element for Needs Review. To determine an accurate position, we’d have to:

  1. determine which ancestor element is used as the anchoring element (who has the first position CSS as it doesn’t have to be the element the pseudo is attached to)
  2. get it’s bounding client rect
  3. determine the pseudo element’s size and position (is it using top and bottom? A set width? Negative margin?)
  4. calculate any CSS transforms (this is the most complicated part)

There’s probably more steps, but this gives the general idea. Until browsers have an API to return the boundingClientRect of the pseudo element, I’m afraid this is the best we can do to avoid false positives on color contrast.

Count me as a vote in agreement that this warning has way too high of a potential for false positive.

@straker could this test be improved in the case that the pseudo-element has defined dimensions? AFAIK it is possible to getComputedStyle on a pseudo. Could get the boundingClientRect of the element it belongs to and then do the math from there. Asking because we’re seeing this warning on e.g. our checkbox control, where the checkbox image is added via pseudo-element. It’s on top of an opacity: 0 native browser checkbox, and doesn’t intersect with the text at all.

image

    '&:before': {
      backgroundColor: 'white',
      border: `1px solid ${IconFillColors.Rest}`,
      borderRadius: 1,
      boxSizing: 'border-box',
      content: `'\\200B'`, // zero-width space
      display: 'inline-block',
      height: BoxDimension,
      position: 'absolute',
      top: 3,
      width: BoxDimension,
    },
    '&.checkbox.checked:before': {
      content: checkboxCheckedSvg(IconFillColors.Rest),
    },

At the moment no. The code was added to help prevent false positives when an element would fail color-contrast even though a pseudo element changed the background color that should have caused it to pass. Since there’s now way to figure out what the pseudo element’s size is (there’s no way to get the boundingClientRect) we decided to settle on just informing the user when a psuedo element is used.

@WilcoFiers maybe this could be an option for color-contrast?