Foundations: accessible naming
Accessible naming separates role, name, description, state, visible text, reference precedence, component APIs, localization, and accessibility-tree testing.
A control can look labeled and still have the wrong accessible name.
An icon tooltip may never enter the name. aria-label can override useful visible text. A shared hidden label can make ten buttons indistinguishable. A description can repeat the name until every focus stop becomes noise.
The Accessible Name and Description Computation 1.2 specification defines how browsers derive flat name and description strings from host-language features, ARIA relationships, content, and hidden references for the accessibility tree.
We will design labels as product content, choose the native source first, understand precedence when ARIA is necessary, separate name from supporting description, and inspect what the browser actually exposes.
The accessible name is not hidden copy. It is the control's identity in another interface.
Visible text, native label elements, alt text, captions, legends, headings, ARIA references, or name-from-content provide candidate text.
The browser follows role-specific rules, labelled-by references, hidden treatment, subtree content, and whitespace normalization.
Assistive technology receives flat strings with semantic role and state; ordering and verbosity affect recognition and action.
Start with role and purpose
A name only makes sense beside the correct semantic role and product action, so identify what the element is and what the user can do before writing label text.
I would pressure-test that decision with four questions:
- Is this a button or link?
- What action or destination matters?
- Does a native element fit?
- Which state changes meaning?
The failure mode here is adding a polished aria-label to the wrong element role. In buttons, links, fields, icons, dialogs, landmarks, tables, menus, custom widgets, error states, repeated actions, localization, and dynamic interfaces where visible text and the name exposed to assistive technology can diverge, that can hide the exact boundary a reviewer or teammate needs to understand. My working artifact would be a role-purpose-name inventory. I want it close enough to the implementation that it can change the work, not created afterward to decorate the story.
The result I would look for is identity aligned with real interaction semantics. That is a narrower claim than saying the whole system improved, but it is also one I can verify and defend.
In practice, I would put a role-purpose-name inventory beside the question “Is this a button or link?” before the first implementation review. The next pass would use “What action or destination matters?” to test the boundary, then “Does a native element fit?” to expose the state most likely to be missed. I would keep “Which state changes meaning?” for the release check because it asks whether the decision still holds outside the ideal path. The work is ready to move when the artifact can explain the choice and the observed result supports identity aligned with real interaction semantics.
Prefer visible native labels
Visible text, label, legend, caption, heading, and alt relationships usually produce more consistent names and help sighted keyboard, voice, cognitive, and screen-reader users together.
The practical review starts here:
- Can the label be visible?
- Does native HTML connect it?
- Will voice users say the same words?
- Is the association programmatic?
Those questions keep hiding the only meaningful action name in ARIA from becoming the default. I would capture the decision in a native-label baseline, then use it while the work is still cheap to change. For interface controls whose purpose is perceivable across modalities, the artifact should make ownership, constraint, and next action visible without requiring a private explanation.
Success would look like one shared language across modalities. If I cannot point to that evidence, I have a direction, not a finished decision.
The implementation move is to make a native-label baseline part of the working surface. I would use it to answer “Can the label be visible?” while scope is still flexible, and “Does native HTML connect it?” before code or content becomes expensive to unwind. During QA, “Will voice users say the same words?” and “Is the association programmatic?” become concrete checks rather than discussion prompts. That sequence turns interface controls whose purpose is perceivable across modalities into something the team can operate and gives me a specific outcome to report: one shared language across modalities.
- VisualThe label is visible
People scanning the page see the same primary action language that keyboard and voice users can reference.
- FocusedName is specific enough
Screen-reader output identifies purpose among neighboring controls without requiring the surrounding layout.
- ReusedComponent context completes meaning
Repeated Edit or Remove controls include the item name through visible or referenced text and remain translatable.
Understand name precedence
ARIA naming properties can override host-language text, so adding aria-label or aria-labelledby may replace rather than supplement a useful visible name.
Before implementation, I would answer:
- Which source currently wins?
- Will ARIA replace content?
- Are referenced IDs valid?
- Can component props collide?
The artifact is an accessible-name precedence test. Its job is to expose the tradeoff early enough that design, engineering, support, or product can disagree with something concrete. The common trap is layering more labels until one seems to be announced; it moves uncertainty downstream and makes the final interface carry a problem the system never resolved.
For me, the useful receipt is intentional final text with no accidental override. That connects an accessible-name contract that starts with native and visible labels, follows computation precedence, uses descriptions only for supporting context, and tests the resulting accessibility tree to an observable result instead of a process claim.
I would test this with one typical case and one boundary case. The typical case should make “Which source currently wins?” easy to answer. The boundary should force a decision about “Will ARIA replace content?” and “Are referenced IDs valid?.” I would record both in an accessible-name precedence test, including the part that stayed unresolved after the first pass. The final check, “Can component props collide?,” is where the artifact earns its place: it either supports intentional final text with no accidental override, or it shows exactly why another iteration is needed.
Use labelled-by for composed context
aria-labelledby can combine visible nodes such as an action and item title, preserving on-screen language while making repeated controls unique.
I would use these prompts during the working review:
- Which references form the name?
- What order will they use?
- Can the item title change?
- Are references unique in the DOM?
If the team slips into giving every row action the same invisible label, the product can still look complete while its operating rule stays ambiguous. I would make a repeated-control labelling pattern the shared reference and keep it small enough to update as evidence changes.
The standard is unique names grounded in visible context. That tells me whether the decision helped the product, not merely whether the document was completed.
The working sequence is small: draft a repeated-control labelling pattern, review it against “Which references form the name?,” implement the narrowest useful path, and then return with evidence for “What order will they use?.” I would use “Can the item title change?” to inspect product consequence and “Are references unique in the DOM?” to decide whether the result is stable enough to ship. This keeps giving every row action the same invisible label visible as a known risk and makes unique names grounded in visible context the release receipt rather than a hopeful conclusion.
| Signal | Decision | Working note |
|---|---|---|
| Name | What this control is or does | Short identity such as Save invoice, Search docs, or Billing email should remain stable and action-oriented. |
| Description | Extra consequence or instruction | Optional context such as file limits, irreversible effect, or formatting belongs after the name when it materially helps. |
| State | Current semantic condition | Expanded, checked, invalid, pressed, required, and unavailable should use the right native or ARIA state rather than words stuffed into the name. |
Keep descriptions supplementary
Descriptions should add consequence, format, constraint, or help that is not already in the name and should not become a second verbose label at every focus.
I would pressure-test that decision with four questions:
- Is this information necessary now?
- Does it repeat the name?
- Should it be visible help?
- Can errors replace or append it?
The failure mode here is placing instructions and errors inside a giant aria-label. In buttons, links, fields, icons, dialogs, landmarks, tables, menus, custom widgets, error states, repeated actions, localization, and dynamic interfaces where visible text and the name exposed to assistive technology can diverge, that can hide the exact boundary a reviewer or teammate needs to understand. My working artifact would be a name-versus-description content matrix. I want it close enough to the implementation that it can change the work, not created afterward to decorate the story.
The result I would look for is concise identity followed by useful optional context. That is a narrower claim than saying the whole system improved, but it is also one I can verify and defend.
In practice, I would put a name-versus-description content matrix beside the question “Is this information necessary now?” before the first implementation review. The next pass would use “Does it repeat the name?” to test the boundary, then “Should it be visible help?” to expose the state most likely to be missed. I would keep “Can errors replace or append it?” for the release check because it asks whether the decision still holds outside the ideal path. The work is ready to move when the artifact can explain the choice and the observed result supports concise identity followed by useful optional context.
Handle hidden references carefully
The computation can include explicitly referenced hidden content under defined conditions, but visually hidden text, display states, and relationship traversal need browser-level verification.
The practical review starts here:
- Is the referenced node hidden?
- Why is it hidden?
- Will the algorithm traverse it?
- Does CSS change exposure?
Those questions keep assuming all hidden text is ignored or always announced from becoming the default. I would capture the decision in a hidden-label fixture set, then use it while the work is still cheap to change. For interface controls whose purpose is perceivable across modalities, the artifact should make ownership, constraint, and next action visible without requiring a private explanation.
Success would look like predictable computed strings across component states. If I cannot point to that evidence, I have a direction, not a finished decision.
The implementation move is to make a hidden-label fixture set part of the working surface. I would use it to answer “Is the referenced node hidden?” while scope is still flexible, and “Why is it hidden?” before code or content becomes expensive to unwind. During QA, “Will the algorithm traverse it?” and “Does CSS change exposure?” become concrete checks rather than discussion prompts. That sequence turns interface controls whose purpose is perceivable across modalities into something the team can operate and gives me a specific outcome to report: predictable computed strings across component states.
Separate semantic state from words
Pressed, expanded, selected, checked, required, invalid, busy, and disabled should be expressed through native or ARIA state so assistive technology can present them consistently.
Before implementation, I would answer:
- Which state is semantic?
- Does the name need to change?
- Can state update independently?
- Is loading removing the control?
The artifact is a role-name-state contract. Its job is to expose the tradeoff early enough that design, engineering, support, or product can disagree with something concrete. The common trap is renaming Save to Saving and deleting the stable action identity; it moves uncertainty downstream and makes the final interface carry a problem the system never resolved.
For me, the useful receipt is clear identity with accurate dynamic state. That connects an accessible-name contract that starts with native and visible labels, follows computation precedence, uses descriptions only for supporting context, and tests the resulting accessibility tree to an observable result instead of a process claim.
I would test this with one typical case and one boundary case. The typical case should make “Which state is semantic?” easy to answer. The boundary should force a decision about “Does the name need to change?” and “Can state update independently?.” I would record both in a role-name-state contract, including the part that stayed unresolved after the first pass. The final check, “Is loading removing the control?,” is where the artifact earns its place: it either supports clear identity with accurate dynamic state, or it shows exactly why another iteration is needed.
Design component naming APIs
Reusable components should accept visible children, label relationships, item context, and descriptions without encouraging every caller to patch semantics with an opaque ariaLabel string.
I would use these prompts during the working review:
- What is the default name source?
- Can context be composed?
- Are invalid combinations rejected?
- Does the type system guide callers?
If the team slips into requiring aria-label for every icon and text button alike, the product can still look complete while its operating rule stays ambiguous. I would make an accessible component naming API the shared reference and keep it small enough to update as evidence changes.
The standard is consistent names that scale across product code. That tells me whether the decision helped the product, not merely whether the document was completed.
The working sequence is small: draft an accessible component naming API, review it against “What is the default name source?,” implement the narrowest useful path, and then return with evidence for “Can context be composed?.” I would use “Are invalid combinations rejected?” to inspect product consequence and “Does the type system guide callers?” to decide whether the result is stable enough to ship. This keeps requiring aria-label for every icon and text button alike visible as a known risk and makes consistent names that scale across product code the release receipt rather than a hopeful conclusion.
Localize complete phrases
Word order, grammar, inflection, item names, and action labels vary by language, so concatenating translated fragments can corrupt both visible and accessible names.
I would pressure-test that decision with four questions:
- Is the full phrase translatable?
- Can item names contain markup?
- Does order change by locale?
- Are hidden and visible copies synchronized?
The failure mode here is concatenating action plus object in English order. In buttons, links, fields, icons, dialogs, landmarks, tables, menus, custom widgets, error states, repeated actions, localization, and dynamic interfaces where visible text and the name exposed to assistive technology can diverge, that can hide the exact boundary a reviewer or teammate needs to understand. My working artifact would be a localized accessible-name fixture. I want it close enough to the implementation that it can change the work, not created afterward to decorate the story.
The result I would look for is natural and equivalent names across supported languages. That is a narrower claim than saying the whole system improved, but it is also one I can verify and defend.
In practice, I would put a localized accessible-name fixture beside the question “Is the full phrase translatable?” before the first implementation review. The next pass would use “Can item names contain markup?” to test the boundary, then “Does order change by locale?” to expose the state most likely to be missed. I would keep “Are hidden and visible copies synchronized?” for the release check because it asks whether the decision still holds outside the ideal path. The work is ready to move when the artifact can explain the choice and the observed result supports natural and equivalent names across supported languages.
Inspect the computed result
Testing should combine browser accessibility-tree output, automated name assertions, keyboard navigation, voice control, screen readers, dynamic updates, duplicates, hidden states, and localization.
The practical review starts here:
- What name does the browser expose?
- Is it unique in context?
- Does it match visible language?
- Which update changes it?
Those questions keep asserting only that an aria-label attribute exists from becoming the default. I would capture the decision in an accessibility-tree naming test matrix, then use it while the work is still cheap to change. For interface controls whose purpose is perceivable across modalities, the artifact should make ownership, constraint, and next action visible without requiring a private explanation.
Success would look like evidence at the interface assistive technology consumes. If I cannot point to that evidence, I have a direction, not a finished decision.
The implementation move is to make an accessibility-tree naming test matrix part of the working surface. I would use it to answer “What name does the browser expose?” while scope is still flexible, and “Is it unique in context?” before code or content becomes expensive to unwind. During QA, “Does it match visible language?” and “Which update changes it?” become concrete checks rather than discussion prompts. That sequence turns interface controls whose purpose is perceivable across modalities into something the team can operate and gives me a specific outcome to report: evidence at the interface assistive technology consumes.
What I would show in the work
The public version needs evidence from the work itself. For this topic, the first five artifacts I would reach for are:
- a role-purpose-name inventory
- a native-label baseline
- an accessible-name precedence test
- a repeated-control labelling pattern
- a name-versus-description content matrix
I would not publish all five at equal weight. One should orient the reader, one should reveal the hardest tradeoff, and one should prove the result. The others can live in a downloadable note or appear as supporting frames. That edit matters because an accessible-name contract that starts with native and visible labels, follows computation precedence, uses descriptions only for supporting context, and tests the resulting accessibility tree becomes harder to understand when every process detail is treated as equally important.
I would also show one rejected direction. The useful version is specific: which option looked attractive, which constraint made it wrong, and what evidence supported the narrower choice. That gives an engineering manager something real to question and keeps the case study from reading like the final answer was obvious from the beginning.
# markup button aria-labelledby='remove item-42' Visible button text supplies Remove; referenced row heading supplies Q3 forecast; native button role and disabled state remain intact.
# tree Remove Q3 forecast, button Description adds 'Moves item to trash for 30 days' once; hidden decorative icon and tooltip do not duplicate output.
# proof keyboard + voice + two screen readers Name is unique, matches visible language, localizes in order, updates after rename, and stays stable during loading state.
Resource path
The practical follow-up I would build is an accessible naming lab with native labels, name-from-content, aria-label, aria-labelledby, aria-describedby, hidden references, repeated controls, icon buttons, groups, dialogs, localization, dynamic updates, accessibility-tree inspection, and screen-reader fixtures. I am treating that as a resource backlog item, not pretending the adjacent downloads below are the same artifact. The related cards cover useful pieces of the workflow today; this specific file should only be published when its examples, fields, and instructions are complete.
The first version should stay concise: context, constraint, decision, evidence, owner, and follow-up. Its value would come from helping someone repeat this exact review, not from adding another generic PDF to the site.
Review checklist
The article-specific review questions are:
- Is this a button or link?
- Can the label be visible?
- Which source currently wins?
- Which references form the name?
- Is this information necessary now?
- Is the referenced node hidden?
- Which state is semantic?
- What is the default name source?
- Is the full phrase translatable?
- What name does the browser expose?
I would add two editorial checks before publishing: can a recruiter find the point in the first minute, and can an engineer trace at least one claim to an implementation or production receipt? If either answer is no, the article needs another edit.
Implementation notes
For interface controls whose purpose is perceivable across modalities, I would write the implementation note before polish. It would name the changed surface, source of truth, owner, failure boundary, and verification path. Those details prevent the principle from floating above the actual code or operational workflow.
The proof signals I care about are specific to this article:
- predictable computed strings across component states
- clear identity with accurate dynamic state
- consistent names that scale across product code
- natural and equivalent names across supported languages
- evidence at the interface assistive technology consumes
I would choose two or three of those signals for the first release rather than instrumenting everything. The strongest pair usually combines one direct behavior check with one operating check: a route and a data query, a keyboard path and a support state, a handler replay and a reconciliation result, or a migration count and a rendered screen.
The follow-up belongs in the note before shipping. It should say what remains temporary, what evidence would trigger another pass, and who owns that decision. That is how the first version stays intentionally narrow without making the boundary invisible.
Case-study packaging
I would structure the case-study version around the four visual lessons already established:
- Accessible identity moves from DOM sources into the accessibility tree.
- A useful control name survives several contexts.
- Name and description do different jobs.
- A naming receipt captures the browser result.
The opening frame explains the product pressure. The middle two show the decision moving through the system. The last frame is the receipt: what was checked, what held, and what remained unresolved. That order lets the reader move from product judgment into implementation detail without reconstructing the whole project first.
I would include one caveat tied to buttons, links, fields, icons, dialogs, landmarks, tables, menus, custom widgets, error states, repeated actions, localization, and dynamic interfaces where visible text and the name exposed to assistive technology can diverge: a data limit, rollout boundary, unsupported state, external dependency, or result that is still directional. A precise caveat makes the evidence easier to trust because it shows where the claim stops.
The final test is whether the page creates a better conversation. If the artifact helps someone ask a sharper question about product judgment, implementation detail, or release proof in a live interview, it belongs in the story.
Interview angle
In an interview, I would explain this through an accessible-name contract that starts with native and visible labels, follows computation precedence, uses descriptions only for supporting context, and tests the resulting accessibility tree. The story should start with the product pressure, then move into the system constraint, the artifact, and the proof. That order keeps the answer grounded. It also gives the interviewer several places to go deeper: data, frontend architecture, design systems, support, migration, accessibility, or release process.
The strongest version of the answer includes a tradeoff. I want to be able to say what I chose, what I left alone, and how I knew the work helped. That is more credible than presenting every project as a clean win.
The hiring signal
An accessible-name model is a hiring signal because it shows I can connect content, semantics, browser computation, component APIs, localization, and assistive-technology verification.
That is the level I want this site to communicate. The work should show taste, but it should also show operating judgment. It should make me look like someone who can enter a real product system, understand the messy middle, ship the useful version, and leave enough proof for the next person to trust it.
Use this after reading.
Practical downloads and templates that turn the article into something you can bring into a product review, implementation pass, or agent workflow.
Design System Contribution Pack
A contribution brief, drift diagnosis, escape-hatch rules, and component-docs template for product teams.
UI PR Risk Review Checklist
A merge-readiness checklist for product intent, states, accessibility, visual durability, and UI implementation risk.
Front-End State Recipes
Reusable recipes for optimistic actions, loading, empty, error, data-transition, and disabled-control states.