Accessibility in Reusable Front‑End Components

Hero image for Accessibility in Reusable Front‑End Components. Image by Chris Barbalis.
Hero image for 'Accessibility in Reusable Front‑End Components.' Image by Chris Barbalis.

Reusable components multiply accessibility decisions.

That is good when the component is built well. One accessible button, form field, modal, or card pattern can help many pages. It is bad when the component is flawed because the same problem repeats everywhere the component appears.

Accessibility belongs inside the component design, not as a final pass over pages that already use it.


Start with the Right Element

The simplest accessibility improvement is often choosing the native element that already has the right behaviour.

Use:

  • a button for actions
  • a link for navigation
  • a label for form controls
  • a heading for section titles
  • a list for lists of related items
  • a fieldset and legend for grouped controls

Custom elements can be made accessible, but they require more work. A clickable div has to be taught things a button already knows.


Give Controls Clear Names

Interactive controls need accessible names.

That includes icononly buttons and links. A search icon, close icon, menu icon, or arrow icon may be visually obvious in context, but it still needs a name exposed to assistive technology.

The article on creating a discernible name for icon links covers this specific problem.

For reusable components, make naming part of the API. Do not leave every usage to solve it differently.


Design Keyboard Behaviour Early

If a component can be operated with a mouse, it usually needs a keyboard path too.

Check:

  • focus reaches the control
  • focus order is logical
  • visible focus styles are present
  • Escape closes overlays where expected
  • arrow keys are used only where the pattern expects them
  • focus returns sensibly after closing a modal or menu

Keyboard behaviour is much harder to add after the component has been used widely because the API may not expose the right state.


Expose State Clearly

Many components have state:

  • expanded or collapsed
  • selected or not selected
  • current page
  • invalid field
  • loading
  • disabled
  • pressed

State should be visible and, where appropriate, exposed semantically. ariaexpanded, ariacurrent, ariainvalid, and disabled are not decorative attributes. They communicate behaviour.

Do not add ARIA casually. Use it when it matches the real component state and native HTML does not already cover the need.


Make Error Handling Part of Form Components

Form fields are a common source of repeated accessibility issues.

A reusable field component should account for:

  • label association
  • hint text
  • error text
  • required state
  • invalid state
  • input ID generation
  • grouped controls

If every form builds those relationships manually, inconsistencies are almost guaranteed.


Test Components in Isolation and in Context

Storybook or another component environment can help catch states early. The article on using Storybook to document frontend components covers why isolated component states are useful.

Still, component testing should not stop there. Test the component in real pages too. Surrounding layout, headings, focus order, and repeated instances can reveal problems that an isolated story misses.

The same idea appears from the API side in component APIs before React Hooks settled. A component that hides state badly is harder to test, document, and make accessible.


Wrapping Up

Reusable components can raise the accessibility quality of a whole site, but only if accessibility is part of their design.

Choose native elements first, make accessible names part of the API, handle keyboard behaviour and state deliberately, and test both isolated and realpage usage. A component is not reusable just because it renders in several places. It is reusable when it carries the right behaviour with it.

Key Takeaways

  • Reusable components repeat accessibility decisions across many pages.
  • Native HTML elements are usually the safest starting point.
  • Accessible names, keyboard behaviour, and state should be part of the component API.
  • Form components need builtin label, hint, error, and invalidstate handling.
  • Test components both in isolation and in real page contexts.

Looking for technical direction?

I support teams that need senior judgement on React, Next.js, headless CMS architecture, performance, migrations, and technical SEO.