Avoid The Accesskey Attribute
ID |
html.no_access_key |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Html |
Tags |
accessibility, reliability |
Rationale
An accesskey claims a keyboard shortcut from a namespace the page does not own. The combination
that reaches it differs per browser and platform, and whatever it is, it can shadow a shortcut the
browser or the assistive technology already uses — screen readers in particular reserve large parts
of the keyboard, so the shortcut that looks like an accessibility feature is the one most likely to
break navigation for the users it was aimed at. There is no way to discover the mapping from the
page, and no way to avoid the collision from the page either.
<button type="submit" accesskey="s">Save</button> <!-- FLAW -->
<a href="/home" accesskey="h">Home</a> <!-- FLAW -->
<input type="text" name="tag" th:accesskey="${key}"> <!-- FLAW — computed, and just as unsafe -->
<button type="submit">Save</button> <!-- OK -->
<input type="text" name="note" data-accesskey="n"> <!-- OK — a data attribute, not the HTML one -->
The value is irrelevant: the collision comes from claiming the key at all, not from which key was
claimed. So an empty or valueless accesskey is reported too, and so is a directive spelling such
as th:accesskey — it puts an accesskey on the rendered page. A namespaced element such as
<h:commandButton> is skipped, as everywhere else in this catalog: it is a template component whose
attributes are the library’s business rather than the HTML element it resembles.
Remediation
Drop the attribute. Where the action really does need to be quick to reach, make it reachable
instead of shortcut-bound: put the control early in the tab order, give it a visible label, and add
a skip link to the region that holds it. An application that needs true shortcuts implements them in
script, on keys the user can see and change, rather than through accesskey.
<a class="skip-link" href="#main">Skip to content</a>
<button type="submit">Save</button>