dequelabs / dequelabs/axe-core
Div inside anchor gets positioned wrong when visually sorting
- Dominant language
- JavaScript
- Stars
- 7.5k
- Forks
- 933
- Avg merge
- 2d 23h
- Merged PRs (30d)
- 17
Description
Given the following DOM:
```html
Hello World
```
Calling `commons.dom.findNearbyElms(img)` results in the anchor, div, and 2 span elements. If we then want to know if any of those elements overlap with the image by running `commons.dom.hasVisualOverlap`, we would expect all those nodes to visually overlap the image. However, the `div` element does not overlap the image but instead is overlapped by the image.
Running the following code:
```js
let data = [];
let imgVNode = axe.utils.getNodeFromTree(img);
[
axe.utils.getNodeFromTree(anchor),
axe.utils.getNodeFromTree(child1),
axe.utils.getNodeFromTree(child11),
axe.utils.getNodeFromTree(child111)
].forEach(neighbor => {
console.log(imgVNode, neighbor)
data.push({
'hasVisualOverlap(img, neighbor)': axe.commons.math.hasVisualOverlap(imgVNode, neighbor),
'hasVisualOverlap(neighbor, img)': axe.commons.math.hasVisualOverlap(neighbor, imgVNode),
});
})
console.table(data)
```
results in:
| neighbor | hasVisualOverlap(img, neighbor) | hasVisualOverlap(neighbor, img) |
| --- | --- | --- |
| a#anchor | true | false |
| div#child1 | false | true |
| span#child11 | true | false |
| span#child111 | true | false |
The reason for this is that that when running `commons.dom.visuallySort` (which `hasVisualOverlap` calls) shows that all the `_stackingOrder` are the same, so we enter the code that looks at positions. The `div` is a block element so returns `0`, but all the other elements are inline so return `2`. This causes the code to put the div above all the other elements, which shouldn't be the case.
Contributor guide
Assessment
This issue has not been assessed yet.