diff --git a/lib/commons/dom/is-visible.js b/lib/commons/dom/is-visible.js index b14e22f01a..2d245428e0 100644 --- a/lib/commons/dom/is-visible.js +++ b/lib/commons/dom/is-visible.js @@ -156,11 +156,21 @@ function isVisible(el, screenReader, recursed) { } // hidden from visual users + const elHeight = parseInt(style.getPropertyValue('height')); + + // ways to hide content visually + const scrollableWithZeroHeight = getScroll(el) && elHeight === 0; + const posAbsoluteOverflowHiddenAndSmall = + style.getPropertyValue('position') === 'absolute' && + elHeight < 2 && + style.getPropertyValue('overflow') === 'hidden'; + if ( !screenReader && (isClipped(style) || style.getPropertyValue('opacity') === '0' || - (getScroll(el) && parseInt(style.getPropertyValue('height')) === 0)) + scrollableWithZeroHeight || + posAbsoluteOverflowHiddenAndSmall) ) { return false; } diff --git a/test/commons/dom/is-visible.js b/test/commons/dom/is-visible.js index 77c6583ba2..71306931b8 100644 --- a/test/commons/dom/is-visible.js +++ b/test/commons/dom/is-visible.js @@ -356,6 +356,13 @@ describe('dom.isVisible', function() { assert.isFalse(axe.commons.dom.isVisible(el.actualNode)); } ); + it('should return false if element is visually hidden using position absolute, overflow hidden, and a very small height', function() { + fixture.innerHTML = + '
StickySticky
'; + var el = document.getElementById('target'); + + assert.isFalse(axe.commons.dom.isVisible(el)); + }); }); describe('screen readers', function() {