role=tooltip with no content: what to check
A tooltip with nothing to announce leaves the control it explains unexplained. squirrel checks every role=tooltip element on the page.
What a tooltip is
role="tooltip" marks a small pop-up that describes the control it belongs to. Unlike a dialog, its own content is its accessible name, and the control points at it with aria-describedby so a screen reader reads the two together.
That makes an empty tooltip pointless. The control announces a description that resolves to nothing, and the user is left with the same question the tooltip was there to answer.
What squirrel checks
One check, aria-tooltip-name, at severity error. It finds every [role="tooltip"] element.
A name is accepted from a non-empty aria-label, an aria-labelledby pointing at an element with text, or the tooltip’s own text content. Unlike the other naming rules, title does not count here.
- Fail with
N tooltip(s) without accessible content. Every offender is listed, asdiv#tip-saveor bare tag name. - Pass with
N tooltip(s) have accessible names. - Info with
No tooltip elements found. aria-tooltip-name-unconfirmedwarns withN tooltip(s) without accessible content may be hidden by a style (unconfirmed)for a tooltip a style may hide in a way squirrel cannot settle.
Hidden tooltips
A tooltip 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" on itself or an ancestor, display: none on itself or an ancestor (set inline or by a <style> rule squirrel can decide), or inside a closed <dialog> or an unopened popover. It still needs a name before it is shown. When every unnamed one is skipped this way, the pass reads All tooltips in the accessibility tree have accessible names, with hiddenWithoutName in its details.
squirrel reads the markup, inline styles and the page’s <style> blocks, the same way as form-labels; see form-labels for what it can and cannot decide. External stylesheets are not read. A tooltip 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, because a theme usually hides that fallback with a rule such as .js .no-js { display: none } once JavaScript runs.
How to fix it
<button aria-describedby="tip-save">Save</button>
<div role="tooltip" id="tip-save">Saves without leaving the page</div>Put the description in the tooltip’s text. The id and the aria-describedby value have to match, and the id has to be unique or the reference lands on the wrong node.
A tooltip rendered empty and filled by script when it opens is reported. Ship the text in the markup and toggle visibility instead, which keeps the description available to the control at all times.
| Rule ID | a11y/aria-tooltip-name |
| Category | Accessibility |
| Scope | Per-page |
| Severity | error |
| Weight | 7/10 |
Enable / disable
Disable this rule
[rules]
disable = ["a11y/aria-tooltip-name"]Disable all Accessibility rules
[rules]
disable = ["a11y/*"]Enable only this rule
[rules]
enable = ["a11y/aria-tooltip-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/duplicate-id-aria: the
aria-describedbyreference resolving to a duplicated or missing id. - a11y/aria-dialog-name: the naming rule for the heavier pop-up.
- a11y/aria-labels: the icon button most tooltips are attached to.
- a11y/aria-valid-attr: typos in
aria-describedbyitself.
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
- The tooltip role, MDN
- aria-describedby, MDN
- Providing accessible names and descriptions, WAI-ARIA Authoring Practices
Check your site
Run squirrel audit https://example.com and open the Accessibility section of the report. Every empty tooltip is listed, with no cap on the count. Signed-out local audits need no account and cost nothing. Signed-in audits spend credits.