Invalid ARIA attribute values and the types they need
aria-checked=yes and aria-level=two are ignored by browsers. squirrel type-checks 26 ARIA attributes against their allowed values.
What a valid ARIA value is
Each ARIA attribute declares a value type. ARIA specifies how a user agent should handle a value outside that type, and the handling is per attribute: some fall back to a default, some are ignored. aria-checked="yes" cannot be relied on to produce a checked state, which is worse than omitting the attribute, because the markup looks correct.
The types are: booleans that take only true or false; booleans that also accept undefined; tristates that add mixed; enumerated tokens with a fixed list; token lists; integers; and numbers.
What squirrel checks
One check, aria-valid-attr-value, at severity error. It reads every aria-* attribute on every element, trims and lowercases the value, and validates it against a table of 26 attributes:
| Type | Attributes | Accepted |
|---|---|---|
| Boolean | aria-busy, aria-disabled, aria-modal, aria-multiline, aria-multiselectable, aria-readonly, aria-required | true, false |
| Boolean or undefined | aria-expanded, aria-grabbed, aria-hidden, aria-selected | true, false, undefined, empty |
| Tristate | aria-checked, aria-pressed | true, false, mixed |
| Token | aria-autocomplete, aria-current, aria-haspopup, aria-invalid, aria-live, aria-orientation, aria-sort | each attribute’s own list |
| Token list | aria-dropeffect, aria-relevant | one or more of that attribute’s tokens |
| Integer | aria-level | a whole number, negative allowed |
| Number | aria-valuemax, aria-valuemin, aria-valuenow | a decimal number, or empty |
- Fail with
N ARIA attribute(s) with invalid values. Items name the element, the attribute and the reason:div[aria-checked]: must be 'true', 'false', or 'mixed', got 'yes', orh2[aria-level]: must be an integer, got 'two'. Up to ten are shown with a count of the rest. - Pass with
All ARIA attribute values are valid.
Attributes outside the table are skipped, so a name that is not in the ARIA vocabulary passes here and fails a11y/aria-valid-attr.
How to fix it
<button aria-pressed="false" aria-controls="filters">Filters</button>
<div id="filters" aria-live="polite">...</div>Use the literal strings the type expects. aria-expanded="1" and aria-expanded="yes" are both outside the type and neither reliably produces a collapsed state. aria-expanded="false" is the value.
Comparison is case-insensitive, so aria-checked="TRUE" passes. Write the values in lowercase anyway, so the markup matches the specification and the next reader.
| Rule ID | a11y/aria-valid-attr-value |
| Category | Accessibility |
| Scope | Per-page |
| Severity | error |
| Weight | 8/10 |
Enable / disable
Disable this rule
[rules]
disable = ["a11y/aria-valid-attr-value"]Disable all Accessibility rules
[rules]
disable = ["a11y/*"]Enable only this rule
[rules]
enable = ["a11y/aria-valid-attr-value"]enable replaces the default ["*"], so this is the only rule selected. Leave disable out: a rule that matches any disable pattern is skipped even when enable names it. Only an enabled setting under a rule’s own [rule_options] table overrides both lists.
Related rules
- a11y/aria-valid-attr: the attribute name itself not existing.
- a11y/aria-required-attr: the attributes a role must declare in the first place.
- a11y/aria-allowed-attr: ARIA attributes that are not allowed on the element carrying them.
- a11y/aria-progressbar-name: progress bars with no accessible name, the widget whose
aria-valuenowthis check type-checks.
Accessibility findings ship in every audit next to the SEO, performance and agent experience rules. See Website security scan with AI for how an agent works through a report.
References
Check your site
Run squirrel audit https://example.com and open the Accessibility section of the report. Each finding names the attribute, the value you supplied and the type it needed. Signed-out local audits need no account and cost nothing. Signed-in audits spend credits.