Skip to content
Case Studies

WCAG compliance as an architecture constraint, not a checklist

compliance standard
WCAG 2.1 AA
design approach
Mobile-first
co-led frontend from scratch
Greenfield
  • Next.js
  • TypeScript
  • Accessibility
  • Tailwind CSS
  • React Testing Library

ContextLink to this section

The people using this portal had specific needs most products assume away. Some navigated with screen readers or keyboard only. Others had cognitive or visual impairments that made dense, poorly structured UIs harder to process. Some had no assistive technology but still relied on clear layout and logical flow more than a typical user would. When that’s your audience, “we’ll worry about accessibility later” isn’t a tradeoff - it’s a failure of the product.

I co-led the greenfield frontend build of the portal they’d use - no existing codebase to retrofit. That meant building the accessibility model into the architecture before a single component existed.

ApproachLink to this section

Treating accessibility as a quality pass at the end is how you get a mostly-compliant product with broken flows. The decision here was to make it a constraint from day one - that shifts the questions you ask when building anything. Not just “does this work?” but “can someone complete this flow with a keyboard?” and “what does VoiceOver announce when this state changes?”

The gap showed up in the flows, not in the report. Axe would pass a multi-step claims form because every input had a label and the heading order was legal. Then you tried it with a keyboard. After you submitted a step, focus stayed on the button you had just pressed, or jumped to the top of the page, so the next heading never became the next stop. A screen-reader user filtering a claims table got a quiet redraw: the rows changed and nothing was announced, so it felt like the control had done nothing. Those were completable flows for a mouse and broken flows for the people this portal was for. Automated green didn’t mean the architecture was done.

or drive it yourself
Axe said the labels were valid. A keyboard user still could not reach the next step. The gap between those two questions is where the architecture had to live.

Practically, that meant three disciplines.

Semantic HTML by default. Not because it’s always easier - custom interactive patterns sometimes make it harder - but because the native semantics carry meaning that ARIA has to reconstruct from scratch otherwise. Start with the right element, then add ARIA only where the element alone isn’t enough.

Manual testing alongside automated checks. Axe and similar tools catch structural problems: missing labels, invalid ARIA, broken heading hierarchy. They don’t catch the interaction problems above. You find those by actually using the interface with a keyboard and a screen reader. There’s no shortcut for that.

React Testing Library as a forcing function. If you write tests correctly - querying by accessible roles rather than class names or test IDs - components without the right semantic roles fail your tests. That pressure is constant. A component that ships without a role didn’t pass a test.

Mobile-first was also the right call. The core audience was likely to include phone-first users, and mobile constraints surface accessibility problems earlier than you’d otherwise catch them - small tap targets, scroll traps, unclear affordances. The two priorities reinforced each other.

OutcomeLink to this section

Shipped a WCAG 2.1 AA compliant portal handling the full workflow. The more meaningful part: that compliance held as the product grew. New form steps, new data views, new interactive patterns - each went through the same disciplines. No accessibility debt accumulated because the structure didn’t allow for it. That’s the difference between building it in and bolting it on.

ReflectionLink to this section

Working on this project changed how I think about accessibility on everything I’ve built since. Not because the techniques were new to me - they weren’t. But working on a product where the users’ situations are this specific makes it harder to treat accessibility as someone else’s concern.

The practical lesson carries beyond projects with these stakes: most of what makes a UI accessible also makes it better for everyone. Keyboard navigation, clear focus states, logical tab order - these aren’t disability accommodations, they’re good interface design. The discipline just forces you to be explicit about things you’d otherwise leave implicit.