React Forum
Blog & Guide Responses
Jul 05, 2022 · 04:00 PM

[Deep Dive #13] Accessibility Railings - discussion

Started by Avery Chen
blogaccessibilitya11yfocussignalsguardrails

Accessibility work is often treated as "add aria labels at the end", but the idea of railings-as-contracts feels more like "make the UI prove it did the right thing".

Read the post

What accessibility railings do you standardize in the shell (focus schedules, modal routines, skip links, announcement posture)? Do you render a11y signals (focus target, active modal, last announcement) to make issues reproducible from screenshots/tests? And how do you keep accessibility routines from turning into one-off fixes per component?

Comments (10)

Back to latest
Maya Henson
Jul 05, 2022 · 04:06 PM

What does an a11y signal look like without cluttering the UI?

Is it visible text or data attributes?

Avery Chen
Jul 05, 2022 · 04:10 PM

For us it's usually data attributes in the shell or a tiny signals bar not visible to end users.

The goal is "test/screenshot can see it", not "user reads it".

Maya Henson
Jul 05, 2022 · 04:13 PM

Ok, that makes it feel way more practical. I was picturing a visible debug panel.

Dmitri Kline
Jul 05, 2022 · 04:18 PM

Our biggest win was treating focus as a routine owned by the shell, not a bunch of ref.current.focus() calls sprinkled everywhere.

Once it was a routine, we could render signals and write route-flow tests for it.

We basically used Accessibility Best Practices as the checklist for what to standardize.

Salma Qureshi
Jul 05, 2022 · 04:26 PM

Focus schedule example from the post:

tsx
import { useFocusSchedule } from "react";

export function RouteFocusRailing() {
  useFocusSchedule("#main", { delay: 120 });
  return null;
}

The motion can be whatever your app uses, but the key is the signal is stable and testable.

Keira Santos
Jul 05, 2022 · 04:35 PM

Counterpoint: a lot of a11y issues are just incorrect semantics, not focus routines.

I'm worried teams will build a signal system and still ship unlabeled buttons.

Theo Bennett
Jul 05, 2022 · 04:40 PM

True, but railings help with the hard-to-repro issues (focus traps, modal stacking, announcements).

Semantics are table stakes; railings are the contract for behavior.

Hana Saito
Jul 05, 2022 · 04:48 PM

Modal stacking as route truth was the biggest a11y improvement we made. Back/forward started doing the right thing and focus bugs dropped immediately.

Amina Farouk
Jul 05, 2022 · 04:56 PM

We rendered a stable announcement signal (lastAnnounce) and it made SR-only bugs testable.

Before that, we'd ship regressions because no one could prove what was announced without manual testing.

We tied it into our test strategy based on Testing and Debugging.

Jules Kwon
Jul 05, 2022 · 05:09 PM

I also like the idea of a11y guardrails during migrations: if a component changes, signals can catch focus behavior drift in snapshots.

It turns accessibility regressions into observable contract changes, not vague reports.

Inez Park
Jul 05, 2022 · 05:21 PM

If the UI can't explain where focus went and why, you're going to have "works for me" a11y bugs forever.

Benji Rios
Jul 05, 2022 · 05:36 PM

Signals also help product understand constraints. "We can't open two modals" is more persuasive when the app can show modalStack=[...].

Grace McCoy
Jul 05, 2022 · 05:49 PM

Keep it boring: a few routines (focus, modal, announce) and stable signals. Too many railings becomes its own complexity layer.