Skip to content

Commit e24cea9

Browse files
marcysuttonWilcoFiers
authored andcommitted
feat(image-alt): require alt text or empty strings (#1260)
* feat(image-alt): require alt text or empty strings The image-alt rule now checks for space characters, and fails if they are present. Empty alt attributes are still fine, and text content is still fine. This fixes cases where ATs do not skip decorative images because of the space characters in the alt attribute. Closes #1174 * chore: include updated build files (there are no actual changes) * chore: rename to alt-space-value, focus on images * fix: PR feedback
1 parent 9930bb9 commit e24cea9

File tree

7 files changed

+58
-17
lines changed

7 files changed

+58
-17
lines changed

lib/checks/label/alt-space-value.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
const validAttrValue = /^\s+$/.test(node.getAttribute('alt'));
2+
return node.hasAttribute('alt') && validAttrValue;

lib/checks/label/alt-space-value.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"id": "alt-space-value",
3+
"evaluate": "alt-space-value.js",
4+
"metadata": {
5+
"impact": "critical",
6+
"messages": {
7+
"pass": "Element has a valid alt attribute value",
8+
"fail": "Element has an alt attribute containing only a space character, which is not ignored by all screen readers"
9+
}
10+
}
11+
}

lib/rules/image-alt.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,5 @@
2121
"role-presentation",
2222
"role-none"
2323
],
24-
"none": []
24+
"none": ["alt-space-value"]
2525
}
Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
{
2-
"id": "landmark-complementary-is-top-level",
3-
"selector": "aside:not([role]), [role=complementary]",
4-
"tags": [
5-
"cat.semantics",
6-
"best-practice"
7-
],
8-
"metadata": {
9-
"description": "Ensures the complementary landmark or aside is at top level",
10-
"help": "Aside must not be contained in another landmark"
11-
},
12-
"all": [],
13-
"any": [
14-
"landmark-is-top-level"
15-
],
16-
"none": []
2+
"id": "landmark-complementary-is-top-level",
3+
"selector": "aside:not([role]), [role=complementary]",
4+
"tags": ["cat.semantics", "best-practice"],
5+
"metadata": {
6+
"description": "Ensures the complementary landmark or aside is at top level",
7+
"help": "Aside must not be contained in another landmark"
8+
},
9+
"all": [],
10+
"any": ["landmark-is-top-level"],
11+
"none": []
1712
}

test/checks/label/alt-space-value.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
describe('alt-space-value', function() {
2+
'use strict';
3+
4+
var checkSetup = axe.testUtils.checkSetup;
5+
var checkContext = axe.testUtils.MockCheckContext();
6+
var check = checks['alt-space-value'];
7+
8+
afterEach(function() {
9+
checkContext.reset();
10+
});
11+
12+
it('should return true if alt contains a space character', function() {
13+
var params = checkSetup('<img id="target" alt=" " />');
14+
assert.isTrue(check.evaluate.apply(checkContext, params));
15+
});
16+
17+
it('should return true if alt contains a non-breaking space character', function() {
18+
var params = checkSetup('<img id="target" alt="&nbsp;" />');
19+
assert.isTrue(check.evaluate.apply(checkContext, params));
20+
});
21+
22+
it('should return false if alt attribute is empty', function() {
23+
var params = checkSetup('<img id="target" alt="" />');
24+
assert.isFalse(check.evaluate.apply(checkContext, params));
25+
});
26+
27+
it('should return false if alt attribute has a proper text value', function() {
28+
var params = checkSetup('<img id="target" alt="text content" />');
29+
assert.isFalse(check.evaluate.apply(checkContext, params));
30+
});
31+
});

test/integration/rules/image-alt/image-alt.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@
1515
<img src="img.jpg" id="pass7" role="none">
1616
<img src="img.jpg" id="pass8" aria-labelledby="ninjamonkeys">
1717
<div role="img" alt="blah" id="violation6"></div>
18+
<img src="img.jpg" id="violation7" alt=" " />
1819
<div role="img" aria-label="blah" id="pass9"></div>
1920
<svg role="img" id="ignore1"><title>SVG Title</title></svg>

test/integration/rules/image-alt/image-alt.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
["#violation3"],
88
["#violation4"],
99
["#violation5"],
10-
["#violation6"]
10+
["#violation6"],
11+
["#violation7"]
1112
],
1213
"passes": [
1314
["#pass1"],

0 commit comments

Comments
 (0)