Skip to content

Commit ab5a011

Browse files
authored
fix(skip-link): identify as skip-link only if the link is offscreen (#2079)
* fix(skip-link): identify as skip-link only if the link is offscreen * fix region test * revert changes, only check offscreen in skip-link
1 parent a7ac380 commit ab5a011

File tree

4 files changed

+44
-11
lines changed

4 files changed

+44
-11
lines changed

lib/rules/skip-link-matches.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
return axe.commons.dom.isSkipLink(node);
1+
return axe.commons.dom.isSkipLink(node) && axe.commons.dom.isOffscreen(node);

test/integration/full/skip-link/skip-link-fail.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
</script>
2121
</head>
2222
<body>
23-
<a href="#fail1-tgt" id="fail1">bad link 1</a>
23+
<a href="#fail1-tgt" style="position: absolute; margin: -10000px" id="fail1"
24+
>bad link 1</a
25+
>
2426
<div id="mocha"></div>
2527
<script src="/test/testutils.js"></script>
2628
<script src="skip-link-fail.js"></script>

test/integration/full/skip-link/skip-link-pass.html

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,21 @@
1111
<script src="/node_modules/mocha/mocha.js"></script>
1212
<script src="/node_modules/chai/chai.js"></script>
1313
<script src="/axe.js"></script>
14+
<style type="text/css">
15+
.sr-only {
16+
border: 0;
17+
clip: rect(0 0 0 0);
18+
clip-path: polygon(0px 0px, 0px 0px, 0px 0px);
19+
-webkit-clip-path: polygon(0px 0px, 0px 0px, 0px 0px);
20+
height: 1px;
21+
margin: -1px;
22+
overflow: hidden;
23+
padding: 0;
24+
position: absolute;
25+
width: 1px;
26+
white-space: nowrap;
27+
}
28+
</style>
1429
<script>
1530
mocha.setup({
1631
timeout: 10000,
@@ -21,22 +36,31 @@
2136
</head>
2237
<body>
2338
<div id="pass1-tgt"></div>
24-
<a href="#pass1-tgt" id="pass1">Link</a>
39+
<a href="#pass1-tgt" class="sr-only" id="pass1">Link</a>
2540

26-
<a href="#pass2-tgt" id="pass2">Link</a>
41+
<a href="#pass2-tgt" style="position: absolute; left: -10000px" id="pass2"
42+
>Link</a
43+
>
2744

2845
<div id="pass3-tgt"></div>
29-
<a href="/#pass3-tgt" id="pass3">Link (angular)</a>
46+
<a href="/#pass3-tgt" class="sr-only" id="pass3">Link (angular)</a>
3047

3148
<div id="canttell1-tgt" style="display:none"></div>
32-
<a href="#canttell1-tgt" id="canttell1">Link</a>
49+
<a href="#canttell1-tgt" class="sr-only" id="canttell1">Link</a>
3350

3451
<!-- since these elements are page links, they needs to be at the bottom
3552
of the test so all the prior links are considered skip links -->
36-
<a name="pass2-tgt"></a>
53+
<header>
54+
<ul>
55+
<li><a id="ignore1" href="/#about">About</a></li>
56+
<li><a id="ignore2" href="/#contact">Contact</a></li>
57+
</ul>
58+
</header>
3759

38-
<a href="foo#bar" id="ignore1">link</a>
39-
<a href="#" id="ignore2">link</a>
60+
<h2 name="pass2-tgt">Heading</h2>
61+
62+
<a href="foo#bar" id="ignore3">link</a>
63+
<a href="#" id="ignore4">link</a>
4064
<div id="mocha"></div>
4165
<script src="/test/testutils.js"></script>
4266
<script src="skip-link-pass.js"></script>

test/rule-matches/skip-link-matches.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ describe('skip-link-matches', function() {
88
rule = axe._audit.rules.find(function(rule) {
99
return rule.id === 'skip-link';
1010
});
11-
link = document.createElement('a');
12-
fixture.innerHTML = '<div id="main"></div>';
11+
fixture.innerHTML =
12+
'<a href="" id="target" style="position: absolute; left: -10000px;">Click me</a><div id="main"></div>';
13+
link = fixture.querySelector('#target');
1314
axe._tree = axe.utils.getFlattenedTree(fixture);
1415
});
1516

@@ -22,6 +23,12 @@ describe('skip-link-matches', function() {
2223
assert.isFunction(rule.matches);
2324
});
2425

26+
it('returns false if the links is onscreen', function() {
27+
link.removeAttribute('style');
28+
link.href = '#main';
29+
assert.isFalse(rule.matches(link));
30+
});
31+
2532
it('returns false if the href attribute does not start with #', function() {
2633
link.href = 'foo#bar';
2734
assert.isFalse(rule.matches(link));

0 commit comments

Comments
 (0)