skip to content

An audit of a car-rental site finds icons announced twice, unnamed icon-only buttons and silent status icons. How do you fix this across the design system rather than screen by screen?

level: seniorimportance: should knowfreq 30%

answer

  1. same root cause behind three findings
  2. defaults decide when nobody does
  3. required name on icon-only controls
  4. hide the icon, never the control
  5. scanners miss bad names

basics

~20 s

All three findings come from defaults deciding accessibility. Fix the contract: icons require an explicit decorative-or-labelled choice, icon-only controls require a name and hide their inner icon, statuses get visible words, and review adds a human listening pass.

solid answer

~40 s

The three findings share one cause: the icon component lets defaults decide, and every default is wrong somewhere — exposed icons duplicate adjacent text, file-name fallbacks read “heart-outline-24”, hidden-by-default icons silence statuses, and an optional name ships “button”. So I fix the **contract**: the icon component requires an explicit decorative-or-labelled choice; the icon-only control requires a non-empty name and always treats its inner icon as decorative; the status component pairs icon and words. I never let teams hide a whole control — a focused element is still exposed, now without a reliable name. Then guidance (the removal test, name rules, standard names for reserved actions) and verification: automated checks for missing names and hidden focusables, plus a human listening pass per platform, because no scanner can tell that “heart” is a bad name.

code

pseudocode · 14 lines
pseudocode
Icon(glyph, meaning)
  meaning is one of:
    Decorative            -> excluded from the accessibility tree
    Labelled(text)        -> exposed as an image, name = text
  if meaning is missing  -> build error (no silent default)

IconOnlyControl(glyph, name, action)
  require name is non-empty
  expose role = button, accessible name = name
  render Icon(glyph, Decorative)   // the control carries the name

Status(glyph, label)
  render Icon(glyph, Decorative)
  render visible text = label       // words carry the meaning

go deeper

for a junior

Recall the three failure shapes — duplicate announcements, unnamed icon-only buttons, hidden meaningful icons — and that each comes from nobody deciding.

for a middle

Explain why hiding a focusable control backfires and why an icon-only control should carry the name while treating its inner icon as decorative.

for a senior

Show a system-level plan: an explicit contract, written name rules, automated checks for what they can catch and human listening for bad names and wrongly hidden icons.

for a principal

Weigh required-choice against decorative-by-default for your product's icon usage, and how you would sequence a migration without stalling feature teams.

## Why screen-by-screen fixing fails The three findings look different but share a cause: the system hands teams an icon component and an icon-only button and lets **defaults** decide accessibility. Every possible default is wrong for some uses: - If icons are exposed by default, icons beside visible text are announced twice (“Air conditioning, image, Air conditioning”). - If the text alternative falls back to the glyph's file name, meaningful icons are announced as “heart-outline-24”. - If icons are hidden by default, a standalone booking-status icon silently disappears for screen reader users. - If an icon-only button does not require a name, it ships announced as just “button”. Fixing four hundred instances on forty screens leaves the default in place, and the next feature reintroduces all three findings. The fix belongs in the component contract, the guidance and the checks. ## 1. Make the decision explicit in the contract The icon component should not have a silent accessibility default. Two defensible designs: | Design | Strength | Risk | |---|---|---| | Required choice: decorative **or** a label | Every use is a conscious decision | A little friction on every use | | Decorative by default; a label makes it meaningful | No friction for the common case | A forgotten label silently hides meaning | The first suits a product where standalone meaningful icons are common, as on a vehicle card. Whichever is chosen, the **icon-only control** is its own component whose name is **required** and non-empty, and which always renders its inner icon as decorative: the control carries the name, so the icon cannot be announced a second time. ## 2. Hide the icon, never the control A tempting shortcut for noisy announcements is to hide a whole icon-only button from assistive technology. WAI-ARIA 1.2 says an element that is currently focused is still exposed even if it or an ancestor is marked hidden — so keyboard and screen reader users still land on it, now without a reliable name. The same specification says that authors who hide visible content from assistive technology must make sure identical or equivalent meaning and functionality are still exposed. The rule for teams is simple: hide decorative icons inside controls; never hide the control. ## 3. Give statuses words Status icons — booking confirmed, payment pending, pickup changed — are decision-critical. The status component should pair the icon with visible text; that serves sighted users, gives assistive technology a natural name and takes the icon out of non-text contrast scope. When a status changes without moving focus, announcing the change is a separate concern owned by the live-announcement guidance, not by the icon. ## 4. Write the guidance The iconography pages should carry: - the decorative-or-meaningful decision as a short test: does removing the icon lose information? - name rules: function not form, verb first, concise, no role word, distinct when repeated; - a table of reserved icon-only actions with their standard names, so “Close” is not “Dismiss” on one screen and “X” on another; - worked examples from the product's own screens, including the vehicle card. ## 5. Verify with the right tool for each finding | Finding | Automated check? | |---|---| | Icon-only control with no name | Usually caught | | Focusable element hidden from assistive technology | Usually caught | | Name that describes the drawing (“Heart”) | Not caught — needs a person | | Decorative icon announced twice | Rarely caught — needs listening | | Meaningful icon wrongly hidden | Not caught — needs someone who knows the meaning | So the plan pairs automated checks in the build with two human steps: designers state each icon's decision in the spec before build, and a reviewer listens to the key flows — search results, vehicle details, booking — with a screen reader on each platform the system ships to. ## 6. Sequence the rollout 1. Inventory every icon use and classify it with the removal test. 2. Ship the new contract alongside the old API, which now warns when no decision is given. 3. Fix the highest-traffic flows first, then the long tail. 4. Turn the warning into an error once usage has migrated. The measure of success is not a clean audit this quarter; it is the same three findings not reappearing in next year's audit.

  • Should the icon component default to decorative or require an explicit choice?
    Both are defensible. Decorative-by-default removes friction but lets a forgotten label silently hide meaning; a required choice costs a word per use but forces the decision. Where standalone meaningful icons are common, require the choice; where icons almost always sit beside text, a decorative default plus a mandatory name on icon-only controls can be enough.
  • How do you catch a meaningful icon that was wrongly marked decorative?
    No automated check can, because it cannot know the icon carries meaning. Catch it upstream by having designers state each icon's decision in the spec, and downstream by a reviewer comparing what a screen reader announces against what a sighted user sees on the key flows. A mismatch — information visible but not heard — is the finding.

saying these in an interview costs you the question

  • Hide the whole icon-only button from assistive technology to stop the noise.
  • Using the glyph's file name as a fallback alternative is a safe default.
  • A clean automated scan proves every icon is correctly labelled.
  • Fixing each flagged screen individually stops the problem from returning.
  • Status icons are fine icon-only as long as each has a text alternative.