axe-core
axe-core copied to clipboard
Color-contrast does not take into account <slot> elements and the light DOM
Product: axe-core && axe Extension Expectation: Correctly Report the Contrast on a Manual Scan Actual: False Reports of an Issue Motivation: This was Previously working
axe-core version: 4.3.5
extension: 4.19.0
To reproduce this issue you can use our test site https://main.wc.design.infor.com/ids-radio/ With Axe Latest version use the extension and Scan the Page.
I can see the page is reporting errors on the label custom element that is almost black on a white background. This previously did work ok (noticed in last week or so). I also wonder how the rules are deployed as we have seen other wierd things like some people seeing it and some not. We see the same thing in our tests which run the puppetteer axe.

I wonder if its because the element is a customElement and the text is linked via a slot.

Hey @tmcconechy - thanks for the report, and thanks for including the URL! I can confirm that I'm seeing the same results you are, and that it does appear to be a bug. I will pass thing along to the correct team members to review.
The issue is being raised as a "needs review" item a.k.a. incomplete, this is expected behavior
@dylanb - what is the expected behavior here? it seems like maybe using any custom elements is not possible with the tool? I'm also pretty sure this did work?
Is there anymore info you need to make it complete? Thanks
Digging into this issue it appears that our color contrast code doesn't take into account custom elements with <slot> correctly. Take the following example which produces a needs review due to overlapping elements:
<my-group>
<my-paragraph>
Let's have some different text!
</my-paragraph>
</my-group>
<script src="/axe.js"></script>
<script>
customElements.define('my-group',
class extends HTMLElement {
constructor() {
super();
const shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.innerHTML = '<div style="position: absolute;"><slot></slot></div>'
}
}
);
customElements.define('my-paragraph',
class extends HTMLElement {
constructor() {
super();
const shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.innerHTML = '<p><slot>My default text</slot></p>'
}
}
);
</script>
Our code thinks the <div> child of the <my-group> custom element is detached from the <my-paragraph> element, where in reality the <slot> moves the element to be a child of the <div>. Our code misses this so assumes the <div> is childless and the position: absolute on it makes it the highest element in the stack.
Validated with the latest axe-core develop branch code base, for the shadow element ,
<div style="position: absolute;"><slot></slot></div>' not seeing any incomplete results , rather seeing pass results for color-contrast

also on extension end , not seeing any results for color-contrast
