axe-core icon indicating copy to clipboard operation
axe-core copied to clipboard

Color contrast should ignore overlapping elements that have transparent background

Open straker opened this issue 3 years ago • 10 comments

Take the following example:

<style>
.overlap {
  position: absolute;
  top: 0;
  left: 0;
  width: 100px;
  height: 100px;
}
</style>

<span>Hello World</span>
<div class="overlap"></div>

This causes an incomplete result for color contrast because the .overlap element is on top of the <span> element in the DOM stack. However since the .overlap element has a transparent background it should just be ignored.

This same problem happens with Material Button components due to the ripple effect element that overlaps the button text.

<button class="mdc-button mdc-button--raised">
  <span class="mdc-button__label">Button</span>
  <div class="mdc-button__ripple"></div>
</button>

straker avatar May 18 '22 14:05 straker

We should look into restricting exactly what is ignored, as images or iframes that overlap won't have a background color but will interfere with the element. So possible solution is to ignore the element if it meets all of the following conditions:

  • has a fully transparent background
  • has no text content
  • has a presentational or no role

straker avatar May 18 '22 19:05 straker

It also can't have CSS filters, thick border, pseudo elements, embedded graphical content like img, canvas, object. There are a ton of ways in which something that at first glance may seem like an empty div, for it to have an impact on content that's behind it.

I think that 9 out of 10 times when we see a transparent element on top of text content, it's there to have some kind of effect on things that are behind it. Why would people put completely empty divs on top of their content?

WilcoFiers avatar May 20 '22 09:05 WilcoFiers

A good example of this is the home page of https://arstechnica.com/. They use empty anchor tags with aria-hidden=true and tabindex=-1 to cover the entire card for the article links which makes every single node in the card return as needs review (165 total color contrast needs review items).

We could scope the requirement to ignore the element based on:

  • does not have text content
  • does not have a background color (i.e. transparent)
  • does not have pseudo elements
  • does not have a border, outline, filter, etc.

straker avatar Jun 03 '22 15:06 straker

Another place this happens on is Material Inputs https://material.angular.io/components/input/overview. The inputs each contain a span which in turn contains the label element for the input. The span overlaps the input, but the label does not. Since the span itself has no background and no direct text children, we should ignore it as well.

straker avatar Oct 03 '22 21:10 straker

Validated with the latest develop branch code base, for the test script:

<style>
.overlap {
  position: absolute;
  top: 0;
  left: 0;
  width: 100px;
  height: 100px;
}
</style>

<span>Hello World</span>
<div class="overlap"></div>

This snippet is giving an incomplete result for color contrast because the .overlap element is on top of the <span> element in the DOM stack.

Image

and with the below test script:

<button class="mdc-button mdc-button--raised">
  <span class="mdc-button__label">Button</span>
  <div class="mdc-button__ripple"></div>
</button>

the ripple effect element that overlaps the button text, so it is passing

padmavemulapati avatar Oct 19 '22 14:10 padmavemulapati

I know this was closed some time ago, but is there any chance to revive #3583 in order to prevent incomplete tests? 😕

CHE1RON avatar Jan 27 '23 14:01 CHE1RON

This was closed by mistake. We're going to look at this again.

WilcoFiers avatar Jul 12 '23 15:07 WilcoFiers

Thanks! 🙏

CHE1RON avatar Jul 12 '23 18:07 CHE1RON

please, fix this!

semisse avatar Mar 07 '24 11:03 semisse