Input fields with no accessible name, ARIA and native
Text boxes, comboboxes and sliders that announce nothing. squirrel checks the nine ARIA input roles alongside native inputs and selects.
What an input field name is
Every field a user types into or drags needs a name, or the screen reader announces only its role: “edit text”, “slider”, “combo box”. The name normally comes from a <label>, and from aria-label or aria-labelledby where a visible label does not fit.
ARIA defines nine input roles for custom widgets: checkbox, combobox, listbox, radio, searchbox, slider, spinbutton, switch and textbox. A <div> carrying one of them needs a name exactly as a native control does, and gets nothing for free.
What squirrel checks
One check, aria-input-field-name, at severity error. It covers three sets: every element with one of the nine input roles; every <input> with no explicit role, excluding types hidden, submit, button, reset and image; and every <textarea> and <select> with no explicit role.
A name is resolved from, in order: aria-label, aria-labelledby, a <label for="..."> matching the field’s id, a wrapping <label>, title, then placeholder.
- Fail with
N input field(s) without accessible names. Items are listed asdiv[role="textbox"],input[name="q"],input[type="text"],textareaorselect, up to ten with a count of the rest. aria-input-field-name-unconfirmedwarns withN input field(s) without accessible names may be hidden by a style (unconfirmed)for unnamed fields a style may hide in a way squirrel cannot settle.- Pass with
All input fields have accessible names, orAll input fields in the accessibility tree have accessible nameswithhiddenWithoutNamewhen unnamed fields were skipped as hidden.
A field out of the accessibility tree has nothing to announce, so it is not reported: one with the hidden attribute (except hidden="until-found"), aria-hidden="true", display: none on itself or an ancestor or visibility: hidden on itself or an ancestor, set inline or by a <style> rule squirrel can decide (such as .closed { display: none }), or inside a closed <dialog> or an unopened popover. It still needs a name before it can be shown. Hiding squirrel cannot settle is reported as unconfirmed instead: an inline style it cannot read exactly, a <style> rule it cannot decide, and, on a page that also loads an external stylesheet, hiding from a <style> rule or visibility inherited from an ancestor. External stylesheets are not read, so a field hidden only by the site’s external CSS, such as a closed modal, is still reported. See What squirrel can see for the details.
A page past squirrel’s style limits (more than 5,000 style rules, a <style> block over the size limit, a very long selector, a no-break or other non-ASCII space in a style block, or a rule nested inside another) is read as unconfirmed for every element a style might hide: the rules past the limit could hide or show any of them, so an unnamed control is reported as unconfirmed, not as a failure. CSS nesting is not read: a nested rule that sets display or visibility (b { @media (min-width: 0) { display: none } }, .a { & .b { display: none } }) leaves the elements it could reach unconfirmed, and a nested rule that sets neither changes nothing.
A control that carries a no-js class, itself or on an ancestor other than <html>, is reported as unconfirmed on a page with an external stylesheet or an @import, with the reason that it may be hidden when JavaScript runs. A theme usually hides that fallback with a rule such as .js .no-js { display: none } in a stylesheet squirrel does not read. The same control on a page whose styles were all read keeps its verdict, and a class such as no-js-hidden is not a marker.
placeholder counts here as a last resort. That makes this rule more forgiving than a11y/form-labels, which rejects it, so a placeholder-only field passes this check and fails that one.
How to fix it
<div role="slider" aria-label="Volume"
aria-valuenow="60" aria-valuemin="0" aria-valuemax="100"
tabindex="0"></div>Name the element that carries the role. A custom widget also needs the state attributes its role requires, which is a separate check.
For native controls a visible <label> is still the better answer, because it names the field and enlarges its click target at the same time.
| Rule ID | a11y/aria-input-field-name |
| Category | Accessibility |
| Scope | Per-page |
| Severity | error |
| Weight | 7/10 |
Enable / disable
Disable this rule
[rules]
disable = ["a11y/aria-input-field-name"]Disable all Accessibility rules
[rules]
disable = ["a11y/*"]Enable only this rule
[rules]
enable = ["a11y/aria-input-field-name"]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/form-labels: the stricter pass over native controls, where
placeholderdoes not count. - a11y/aria-toggle-field-name: checkboxes, radios and switches specifically.
- a11y/select-name: dropdowns specifically.
- a11y/aria-required-attr: the state attributes a custom input role has to declare.
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. Custom widgets and native controls are listed together, each with a selector. Signed-out local audits need no account and cost nothing. Signed-in audits spend credits.