"We’ll add accessibility before launch" is the most expensive lie teams tell themselves. Accessibility added late is rebuild work disguised as fixes. Accessibility-first means the product is usable by everyone from the first commit — and that’s easier and cheaper than retrofitting. This is how we approach WCAG 2.1 AA compliance at Schedars.
TL;DR
Accessibility-first ≠ writing tons of ARIA. It means semantic HTML by default, color contrast that meets 4.5:1, keyboard navigation that doesn’t skip elements, focus management on dynamic content, alt text on every image. Cover those six and you handle 80% of WCAG 2.1 AA. Automate the basics in CI; manually test with VoiceOver and keyboard once per sprint.
Why accessibility-first (not "we’ll add it later")
Three reasons. First: it’s the law in most markets — the US (ADA), EU (EAA), Canada (AODA). Public-facing products with non-trivial revenue have legal exposure. Second: 15-20% of users have disabilities that accessibility design directly affects — that’s revenue you’re leaving on the table. Third: accessibility-first design tends to also be better design for everyone (semantic structure, predictable interactions, keyboard-first navigation).
Retrofitting accessibility costs 3-5x what doing it right from the start does. We’ve audited products that needed 4 weeks of fix work because color contrast was set in 50 places, focus state was broken in dropdowns, and ARIA was layered on top of broken HTML. Accessibility-first means none of those exist.
The Big Six (cover 80% of issues)
Semantic HTML
Use buttons for buttons, links for links, headings for hierarchy, lists for lists. Don’t reinvent <button> with <div onClick>. Browsers, assistive tech, and search engines all rely on the semantics. The shortest and most reliable accessibility win is "use the right HTML element for the job".
Color contrast
WCAG 2.1 AA requires 4.5:1 for normal text, 3:1 for large text and UI components. Pick your design tokens to pass these from the start — don’t check colors after the design is done. Tools: Stark for Figma, axe DevTools for browser, Lighthouse "Accessibility" audit for the catch-all. Common violations: light gray placeholder text, accent-on-accent buttons, "subtle" disabled states.
Keyboard navigation
Every interactive element must be reachable and operable via Tab / Shift-Tab / Enter / Space / arrow keys. No keyboard traps (modals must be escapable). Focus order should match visual order. Test by unplugging your mouse and tabbing through every page — you’ll find issues in 5 minutes.
Focus management
When dynamic content appears (modal opens, route changes, form submitted), focus should move to a sensible place — usually the first focusable element in the new content, or a "page-level" announcement. After modals close, focus should return to the trigger. Without focus management, screen reader users get lost on every interaction.
Alt text
Every <img> needs an alt attribute. Decorative images: alt="" (empty, deliberately). Informative images: a short description of what the image conveys. Don’t describe the image visually ("photo of a person smiling") — describe its purpose ("Sarah, founder of Acme Co"). Auto-generated alt text is worse than empty alt text.
Form labels and errors
Every input needs a programmatically associated label (label-for or aria-labelledby). Errors need to be announced to screen readers (aria-live="polite" or role="alert"). Inline error messages near the input. Don’t use color alone to indicate error state — pair color with an icon or text.
Tools we run on every PR
- axe-core via @axe-core/playwright in E2E tests — catches 30-50% of WCAG issues automatically
- eslint-plugin-jsx-a11y in lint config — catches missing alts, label/input mismatches, button vs div misuse at edit-time
- Lighthouse CI accessibility score thresholded at 95 — blocks merge below that
- Pa11y CI on top-5 user-flow pages — catches DOM-level issues automation can detect
What automation can’t catch (manual once per sprint)
- VoiceOver / NVDA navigation feels right (do landmarks help? are headings logical?)
- Keyboard-only completion of top 3 user flows
- Magnification at 200% — does the layout still work?
- High contrast mode (Windows or macOS Increase Contrast) — do critical UI elements remain visible?
- Cognitive load: are error messages clear? are forms simple? is timing forgiving?
Common patterns done right
Modals
Trap focus inside while open, restore focus on close, close on Escape, announced via aria-modal + aria-labelledby. Use the native <dialog> element on browsers that support it (which is everything modern); polyfill or carefully replicate the behavior if you can’t.
Dropdowns
aria-expanded on the trigger, aria-controls pointing to the listbox, role="listbox" on the menu, role="option" on each item. Arrow keys navigate, Enter selects, Escape closes. Don’t hijack Tab — let it move focus out of the dropdown to the next interactive element.
Carousels
They’re an accessibility minefield by default. Provide pause/play controls. Don’t auto-advance without user control. Provide skip links to bypass them. Honestly: question whether you need a carousel at all — they have terrible accessibility and conversion outcomes both.
What we ship at Schedars
We hit Lighthouse Accessibility 95+ on every project. Recent wins: a healthcare intake form that passed full WCAG 2.1 AA audit on first review (Pa11y + manual VoiceOver test), and an e-commerce storefront that surfaced a 3% revenue lift from previously-blocked checkout flows once keyboard navigation was fixed. Accessibility isn’t a niche concern — it’s a quality bar that pays for itself.
Bottom line
Accessibility-first development is mostly discipline: semantic HTML, color contrast, keyboard navigation, focus management, alt text, form labels. Automate the catchable issues in CI; manually test once per sprint. The cost is a few hours per project and the upside is legal compliance, +15% addressable market, and better design for everyone.
Need an accessibility audit on your existing site or a WCAG-AA-from-day-one build? Tell us the scope — we’ll send back a prioritized fix list within a day.