diff --git a/lib/commons/dom/find-nearby-elms.js b/lib/commons/dom/find-nearby-elms.js
index 8bfbfa8a64..fc77a315de 100644
--- a/lib/commons/dom/find-nearby-elms.js
+++ b/lib/commons/dom/find-nearby-elms.js
@@ -1,8 +1,10 @@
import createGrid from './create-grid';
+import { memoize } from '../../core/utils';
export default function findNearbyElms(vNode, margin = 0) {
/*eslint no-bitwise: 0*/
const gridSize = createGrid();
+ const selfIsFixed = hasFixedPosition(vNode);
if (!vNode._grid?.cells?.length) {
return []; // Elements not in the grid don't have ._grid
}
@@ -18,10 +20,16 @@ export default function findNearbyElms(vNode, margin = 0) {
const neighbors = [];
loopGridCells(gridCells, boundaries, vNeighbor => {
- if (vNeighbor && vNeighbor !== vNode && !neighbors.includes(vNeighbor)) {
+ if (
+ vNeighbor &&
+ vNeighbor !== vNode &&
+ !neighbors.includes(vNeighbor) &&
+ selfIsFixed === hasFixedPosition(vNeighbor)
+ ) {
neighbors.push(vNeighbor);
}
});
+
return neighbors;
}
@@ -37,3 +45,13 @@ function loopGridCells(gridCells, boundaries, cb) {
}
}
}
+
+const hasFixedPosition = memoize(vNode => {
+ if (!vNode) {
+ return false;
+ }
+ if (vNode.getComputedStylePropertyValue('position') === 'fixed') {
+ return true;
+ }
+ return hasFixedPosition(vNode.parent);
+});
diff --git a/test/commons/dom/find-nearby-elms.js b/test/commons/dom/find-nearby-elms.js
index 548ba3fc64..ceef24d37c 100644
--- a/test/commons/dom/find-nearby-elms.js
+++ b/test/commons/dom/find-nearby-elms.js
@@ -1,11 +1,10 @@
-describe('findNearbyElms', function () {
- 'use strict';
- var fixtureSetup = axe.testUtils.fixtureSetup;
- var findNearbyElms = axe.commons.dom.findNearbyElms;
- var fixture;
+describe('findNearbyElms', () => {
+ let fixture;
+ const fixtureSetup = axe.testUtils.fixtureSetup;
+ const findNearbyElms = axe.commons.dom.findNearbyElms;
function getIds(vNodeList) {
- var ids = [];
+ const ids = [];
vNodeList.forEach(function (vNode) {
if (vNode.props.id && vNode.props.id !== 'fixture') {
ids.push(vNode.props.id);
@@ -14,8 +13,8 @@ describe('findNearbyElms', function () {
return ids;
}
- describe('in the viewport', function () {
- beforeEach(function () {
+ describe('in the viewport', () => {
+ beforeEach(() => {
fixture = fixtureSetup(
'
0
' +
'1
' +
@@ -30,19 +29,19 @@ describe('findNearbyElms', function () {
);
});
- it('returns node from the same grid cell', function () {
- var nearbyElms = findNearbyElms(fixture.children[1]);
+ it('returns node from the same grid cell', () => {
+ const nearbyElms = findNearbyElms(fixture.children[1]);
assert.deepEqual(getIds(nearbyElms), ['n0', 'n2', 'n3']);
});
- it('returns node from multiple grid cells when crossing a boundary', function () {
- var nearbyElms = findNearbyElms(fixture.children[5]);
+ it('returns node from multiple grid cells when crossing a boundary', () => {
+ const nearbyElms = findNearbyElms(fixture.children[5]);
assert.deepEqual(getIds(nearbyElms), ['n3', 'n4', 'n6']);
});
});
- describe('on the edge', function () {
- beforeEach(function () {
+ describe('on the edge', () => {
+ beforeEach(() => {
fixture = fixtureSetup(
'0
' +
'1
' +
@@ -50,19 +49,44 @@ describe('findNearbyElms', function () {
);
});
- it('ignores cells outside the document boundary', function () {
- var nearbyElms = findNearbyElms(fixture.children[0]);
+ it('ignores cells outside the document boundary', () => {
+ const nearbyElms = findNearbyElms(fixture.children[0]);
assert.deepEqual(getIds(nearbyElms), ['n2']);
});
- it('returns no neighbors for off-screen elements', function () {
- var nearbyElms = findNearbyElms(fixture.children[1]);
+ it('returns no neighbors for off-screen elements', () => {
+ const nearbyElms = findNearbyElms(fixture.children[1]);
assert.deepEqual(getIds(nearbyElms), []);
});
- it('returns element partially on screen as neighbors', function () {
- var nearbyElms = findNearbyElms(fixture.children[2]);
+ it('returns element partially on screen as neighbors', () => {
+ const nearbyElms = findNearbyElms(fixture.children[2]);
assert.deepEqual(getIds(nearbyElms), ['n0']);
});
});
+
+ describe('when some nodes are fixed', () => {
+ beforeEach(() => {
+ fixture = fixtureSetup(
+ '' +
+ '
1
' +
+ '
2
' +
+ '
' +
+ '3
' +
+ '4
'
+ );
+ });
+
+ it('skips fixed position neighbors when not fixed', () => {
+ const n3 = axe.utils.querySelectorAll(fixture, '#n3')[0];
+ const nearbyElms = findNearbyElms(n3);
+ assert.deepEqual(getIds(nearbyElms), ['n4']);
+ });
+
+ it('includes only fixed position neighbors when fixed', () => {
+ const n1 = axe.utils.querySelectorAll(fixture, '#n1')[0];
+ const nearbyElms = findNearbyElms(n1);
+ assert.deepEqual(getIds(nearbyElms), ['n0', 'n2']);
+ });
+ });
});
diff --git a/test/integration/rules/target-size/target-size.html b/test/integration/rules/target-size/target-size.html
index 794f00a0b7..05e714c2df 100644
--- a/test/integration/rules/target-size/target-size.html
+++ b/test/integration/rules/target-size/target-size.html
@@ -5,6 +5,13 @@
}
+
+
+ Wide link
+ x
+
+