Skip to content

SEO

Fixing Accessible Names without guessing

Stop inventing aria-label strings from screenshots. Use the computed accessible name, fix the association, and verify the public control still announces something usable.

· by Maya Okonkwo

Fixing Accessible Names without guessing

Guessing a label from a Figma frame is how you ship a second bug on top of the first. The control already sits on the public surface. Assistive tech asks for a name. You paste aria-label="Close modal maybe?" because the screenshot looked like a close control. Sighted QA still sees an X. A screen reader user gets a string that never matched the visible affordance, or worse, a string that lies about what the button does.

SlaySlop's Accessible names check is blunt about the signal: it "finds controls and content that lack usable accessible labels." Usable is the word that matters. Presence of an attribute is not the same as a name someone can act on. This post is about fixing that miss without inventing poetry for the accessibility tree.

Outcome you want

After the fix, the control has a computed accessible name that matches what a careful human would call it, and that name still holds after a real browser render. The ticket closes against a URL and a control, not against a vibe that "a11y looked fine."

Boundaries before you edit markup

Accessible names are one accessibility signal. SlaySlop also catalogs Document semantics (structural signals for assistive technology), an Accessibility audit that runs automated checks in a rendered browser page, and Viewport configuration for mobile viewport and zoom-safe behavior. Closing a naming finding does not retire those.

SlaySlop itself is read-only. It does not edit your site. Only scan URLs you own, manage, or have permission to test. A naming pass on the public DOM is not a WCAG conformance certificate and not a pentest. Treat findings as public-surface hygiene with evidence, then fix in your own repo.

Static HTML is a weak witness. Icon buttons, cookie dismissals, and header actions often mount after hydration. The Performance and accessibility product framing is that the site opens in a real browser so runtime behavior can be measured. Fix and verify against that same rendered surface.

Loading diagram.

Happy path: read the name the browser already computes

Do not start in a design file. Start on the page the finding points to. In Chromium DevTools, select the control and open the Accessibility pane. The computed name is the string assistive tech will lean on. If it is empty, generic ("button"), whitespace, or obviously wrong, that is your bug. If it already looks right after a recent deploy, re-scan before you invent a duplicate aria-label.

html
<!-- Prefer visible text when the UI already shows it -->
<button type="button">Close</button>

<!-- Prefer an associated label for inputs -->
<label for="company">Company name</label>
<input id="company" name="company" type="text" autocomplete="organization" />

<!-- labelledby when the visible explanation lives elsewhere -->
<p id="export-hint">Download the CSV of verified findings.</p>
<button type="button" aria-labelledby="export-hint">Download</button>

<!-- Last resort: explicit aria-label on an icon-only control -->
<button type="button" aria-label="Close notification">
  <svg aria-hidden="true" focusable="false"><!-- icon paths --></svg>
</button>

The order is deliberate. Visible text and real <label for> associations survive redesigns better than a pile of one-off aria-label strings. aria-labelledby keeps a single source of truth when the explanation is already on the page. aria-label is for controls that truly have no visible text, not for papering over a missing design token.

bash
# Permissioned smoke: confirm the route still answers before you dive into DevTools
curl -sI "https://staging.example.com/pricing" | sed -n '1,15p'

Headers and status codes do not prove names exist. They only prove you are looking at the right host. After that, tab to the control, read the computed name, change the markup, reload, read it again.

What guessing looks like in production

I keep seeing three shortcuts that feel fast and age badly.

Screenshot linguistics. Someone writes aria-label="Menu" on a button that visibly says "Products". Voice control users who say "click Products" miss. Sighted users think the UI is clear. The public surface now has two names for one control.

Placeholder as label. An email field with placeholder="Work email" and no <label> may look labeled in a light theme mock. Placeholder text is not a reliable accessible name, disappears on input, and often fails contrast. Fix the association. Keep the placeholder as hint copy if you must.

Shared icon button with an optional label prop. The component ships with aria-label undefined by default. Every instance inherits the hole. A scanner that renders the page will keep finding anonymous buttons until the API makes the name required. Do not "fix" twenty call sites with twenty slightly different strings if the design system can enforce one pattern.

Whitespace labels and aria-label="button" are not usable labels. They satisfy a naive "attribute exists" mental model and still fail the product language SlaySlop publishes.

Fix against evidence, not against fear

When SlaySlop reports an Accessible names issue, the useful part is route linkage: findings stay tied to the page where they were observed. Open that URL. Identify the control. Prefer the smallest change that produces a usable computed name. Then run the page again in a real browser. If you use fix prompts from a SlaySlop report, treat them as paste-ready starting points grounded in that scan's evidence, not as unsupervised commits to production.

Re-scan after deploy. Scheduled rescans and score history exist so you can see whether a naming fix held or a new icon cluster reintroduced the miss. That is hygiene, not theater.

Related checks to keep in the same triage lane

Keep Accessible names next to Document semantics and the broader Accessibility audit when you triage. Naming without structure still leaves assistive tech guessing how the page is organized. Structure without names leaves operable controls anonymous. Viewport mistakes can make the same controls hard to use on mobile even when the name string is perfect.

For the published definition of this check, see Accessible names and the checks catalog. If you want the same public URL re-checked in a real browser with the finding kept next to its page evidence, start from a SlaySlop scan you are allowed to run.