Accessibility in React, Vue, Angular, and Svelte
TABLE OF CONTENTS
- Key Takeaways
- Framework-Neutral Baseline
- React: What It Enables and What It Breaks
- Next.js: Routing and Announcements
- Angular: CDK A11y Primitives
- Vue: Structure and Focus Management
- SvelteKit: Compile-Time Warnings
- Cross-Framework Hard Parts
- The Scalable Strategy
- Framework Selection Is Not Strategy
- FAQ
- Related Resources
Frameworks don't make apps accessible; patterns do. React, Vue, Angular, and Svelte each provide tools that can help or hinder accessibility, but none automatically produce accessible applications. A React app built with semantic HTML, proper labeling, and focus management is accessible. A React app built with divs, custom click handlers, and no keyboard support isn't—regardless of how sophisticated the framework is.
Modern frameworks introduce new failure modes (routing, hydration, dynamic UI) but also enable strong solutions (component contracts, linting, route announcements). Client-side routing breaks the traditional page-load model that screen readers expect. Hydration can create timing issues where server content differs from client content. But frameworks also let you build accessible component libraries that enforce good patterns across your entire application.
The best approach is framework-agnostic: semantics-first, patterns-based, pipeline-enforced. Start with semantic HTML. Follow ARIA Authoring Practices for custom widgets. Enforce with linting and CI. Validate with assistive technology testing. This approach works regardless of whether you're using React, Vue, Angular, Svelte, or the next framework that emerges. WebAIM's 2024 Million report found 95.9% of home pages failing accessibility checks—framework choice isn't solving the problem.
Key Takeaways
Framework-agnostic fundamentals matter more than framework-specific features.
- Semantic HTML is the foundation – Every framework renders HTML; use the right elements regardless of framework syntax
- Focus management requires explicit attention – SPAs don't automatically manage focus on navigation; every framework requires intentional implementation
- Component contracts encode accessibility – TypeScript props that require accessible names, labels, and handlers make accessibility enforceable
- Routing accessibility is framework-specific – Each framework has different approaches to announcing route changes; know your framework's patterns
- Linting and testing work across frameworks – eslint-plugin-jsx-a11y (React), axe-core (all)—tools exist for every major framework
Framework-Neutral Baseline
Before framework-specific considerations, the fundamentals apply everywhere.
What Every Framework Must Get Right
+--------------------------+----------------------------------------------------+
| Fundamental | Implementation |
+--------------------------+----------------------------------------------------+
| Semantic HTML | Use `<button>`, `<a>`, `<input>`, not divs |
+--------------------------+----------------------------------------------------+
| Correct labeling | Every input has associated label; every button has accessible name |
+--------------------------+----------------------------------------------------+
| Keyboard operability | All interactions work with keyboard; focus is visible |
+--------------------------+----------------------------------------------------+
| Focus management | Modals trap focus; navigation moves focus appropriately |
+--------------------------+----------------------------------------------------+
| ARIA when needed | Follow ARIA APG patterns for custom widgets |
+--------------------------+----------------------------------------------------+
| Testing | Lint, runtime tests, AT verification |
+--------------------------+----------------------------------------------------+ARIA Authoring Practices Guide
The W3C ARIA Authoring Practices Guide provides implementation patterns for:
- Accordions
- Comboboxes
- Dialogs (modal and non-modal)
- Menus and menubars
- Tabs
- Tree views
- And many more
These patterns are framework-agnostic. The APG shows what keyboard behavior, ARIA attributes, and focus management a pattern needs. You implement it in your framework of choice.
React: What It Enables and What It Breaks
React is the most popular frontend framework and has extensive accessibility documentation.
What React Documentation Says
React's accessibility documentation notes that React fully supports building accessible websites, largely by using standard HTML techniques. The framework doesn't add barriers—but it also doesn't automatically add accessibility.
Common React Pitfalls
+-----------------------------------------+----------------------------------------------------+
| Pitfall | Why It Happens |
+-----------------------------------------+----------------------------------------------------+
| Custom components hiding semantics | Wrapping `<button>` in custom component that renders `<div>` |
+-----------------------------------------+----------------------------------------------------+
| Focus management forgotten | Modals open without moving focus; close without returning it |
+-----------------------------------------+----------------------------------------------------+
| Portals confusing tab order | Content rendered outside DOM tree creates unexpected navigation |
+-----------------------------------------+----------------------------------------------------+
| Fragments breaking structure | Overuse of fragments can create heading hierarchy issues |
+-----------------------------------------+----------------------------------------------------+
| State changes without announcements | Content updates without aria-live |
+-----------------------------------------+----------------------------------------------------+React Solutions
Component contracts via TypeScript:
interface ButtonProps {
// Requires some form of accessible name
children?: React.ReactNode;
'aria-label'?: string;
onClick: () => void;
}Focus management:
const dialogRef = useRef(null);
useEffect(() => {
if (isOpen) dialogRef.current?.focus();
}, [isOpen]);Linting: eslint-plugin-jsx-a11y provides extensive JSX-specific rules.
MDN React Guidance
MDN's React accessibility tutorial emphasizes focus management to reduce confusion for keyboard and screen reader users. The tutorial walks through implementing proper focus management in React applications.
Next.js: Routing and Announcements
Next.js adds routing and rendering concerns on top of React.
What Next.js Provides
Next.js accessibility documentation highlights built-in features including route announcements that help screen readers understand page transitions.
Route Announcements
When using next/router, Next.js can announce route changes to screen readers. This addresses a fundamental SPA problem: traditional page loads trigger screen reader announcements, but client-side navigation doesn't.
Common Next.js Pitfalls
+---------------------------------------------+----------------------------------------------------+
| Pitfall | Why It Happens |
+---------------------------------------------+----------------------------------------------------+
| Client navigation without announcements | Custom navigation bypasses Next.js announcement |
+---------------------------------------------+----------------------------------------------------+
| Head management issues | Page titles not updating correctly |
+---------------------------------------------+----------------------------------------------------+
| Focus not moving on navigation | User stays at old position after route change |
+---------------------------------------------+----------------------------------------------------+
| Hydration mismatches | Server/client content differs, confusing AT |
+---------------------------------------------+----------------------------------------------------+Next.js Solutions
Verify route announcements work: Test with a screen reader after navigation. You should hear the new page announced.
Update document title:
import Head from 'next/head';
export default function ProductPage() {
return (
<>
<Head>
<title>Product Name - Store</title>
</Head>
{/* page content */}
</>
);
}Consider focus management: After navigation, focus should typically move to the main content heading or the top of new content.
Angular: CDK A11y Primitives
Angular provides the Component Dev Kit (CDK) with dedicated accessibility utilities.
Angular Accessibility Best Practices
Angular's accessibility guide mentions the CDK a11y package, including LiveAnnouncer for screen reader messages via aria-live regions and FocusTrap for managing focus within modals.
CDK A11y Features
+--------------------+----------------------------------------------------+
| Feature | Purpose |
+--------------------+----------------------------------------------------+
| LiveAnnouncer | Programmatically announce messages to screen readers |
+--------------------+----------------------------------------------------+
| FocusTrap | Keep focus within a container (for modals) |
+--------------------+----------------------------------------------------+
| FocusMonitor | Track focus origin (keyboard vs mouse) |
+--------------------+----------------------------------------------------+
| ListKeyManager | Handle keyboard navigation in lists |
+--------------------+----------------------------------------------------+Common Angular Pitfalls
+---------------------------------+----------------------------------------------------+
| Pitfall | Why It Happens |
+---------------------------------+----------------------------------------------------+
| Complex Material components | Material components have accessibility, but misuse breaks it |
+---------------------------------+----------------------------------------------------+
| Focus trapping issues | Not using CDK FocusTrap for custom modals |
+---------------------------------+----------------------------------------------------+
| Over-reliance on attributes | Adding ARIA without understanding behavior |
+---------------------------------+----------------------------------------------------+
| Template-driven issues | ngIf/ngFor creating unexpected DOM changes |
+---------------------------------+----------------------------------------------------+Angular Solutions
Use CDK primitives:
import { LiveAnnouncer } from '@angular/cdk/a11y';
constructor(private announcer: LiveAnnouncer) {}
announceMessage(message: string) {
this.announcer.announce(message);
}Focus trap for modals:
<div cdkTrapFocus [cdkTrapFocusAutoCapture]="true">
<!-- Modal content -->
</div>Vue: Structure and Focus Management
Vue emphasizes progressive enhancement and template-based components.
Vue Accessibility Guide
Vue's accessibility documentation emphasizes structuring content with proper headings and includes practical patterns for focus management with routing.
Common Vue Pitfalls
+-----------------------------------------+----------------------------------------------------+
| Pitfall | Why It Happens |
+-----------------------------------------+----------------------------------------------------+
| Template convenience over semantics | Using divs when buttons/links are appropriate |
+-----------------------------------------+----------------------------------------------------+
| Missing heading hierarchy | SPAs without clear document structure |
+-----------------------------------------+----------------------------------------------------+
| Router focus management | Vue Router doesn't manage focus by default |
+-----------------------------------------+----------------------------------------------------+
| v-if/v-show confusion | Content hidden but still focusable or announced |
+-----------------------------------------+----------------------------------------------------+Vue Solutions
Router focus management:
router.afterEach((to, from) => {
// Move focus to main content after navigation
nextTick(() => {
const mainContent = document.querySelector('main');
mainContent?.focus();
});
});Component props requiring accessibility:
interface ButtonProps {
label: string; // Required accessible name
onClick: () => void;
}SvelteKit: Compile-Time Warnings
Svelte takes a unique approach with compile-time accessibility checks.
SvelteKit Accessibility Documentation
SvelteKit's accessibility documentation states the framework strives to provide an accessible platform by default and includes compile-time accessibility checks. Warnings appear during compilation for common accessibility mistakes.
What Compile-Time Catches
+------------------------------+----------------------------------------------------+
| Pattern | Warning |
+------------------------------+----------------------------------------------------+
| `<img>` without alt | A11y: `<img>` element should have an alt attribute |
+------------------------------+----------------------------------------------------+
| onClick without keyboard | A11y: visible, non-interactive elements should not have on:click |
+------------------------------+----------------------------------------------------+
| Invalid ARIA | A11y: unknown aria attribute |
+------------------------------+----------------------------------------------------+The Responsibility Note
The SvelteKit documentation explicitly notes that developers remain responsible for writing accessible application code. Compile-time checks are guardrails, not autopilot.
Common SvelteKit Pitfalls
+-----------------------------------------+----------------------------------------------------+
| Pitfall | Why It Happens |
+-----------------------------------------+----------------------------------------------------+
| Ignoring compiler warnings | Treating a11y warnings as noise |
+-----------------------------------------+----------------------------------------------------+
| tabindex overuse | Using tabindex to "fix" focus instead of fixing structure |
+-----------------------------------------+----------------------------------------------------+
| Store changes without announcements | Reactive updates not announced to AT |
+-----------------------------------------+----------------------------------------------------+SvelteKit Solutions
Treat warnings as errors: Configure your build to fail on accessibility warnings.
Follow the patterns: SvelteKit's official examples demonstrate accessible patterns—follow them.
Cross-Framework Hard Parts
Some accessibility challenges appear regardless of framework.
Modal Dialogs
Every framework struggles with modals:
- Focus must move into modal on open
- Focus must be trapped within modal
- Escape must close modal
- Focus must return to trigger on close
The ARIA APG dialog pattern documents correct behavior. Implementation varies by framework, but the requirements are universal.
Menus and Dropdowns
Custom menus need:
- Proper role and aria attributes
- Arrow key navigation
- Type-ahead search
- Escape to close
- Focus management
Again, ARIA APG provides the pattern; frameworks provide implementation approaches.
Drag and Drop
WCAG 2.2 requires alternatives to dragging operations. This affects:
- Sortable lists
- Kanban boards
- File uploads
- Any drag-based interaction
Provide keyboard and click alternatives for all drag operations.
Authentication
WCAG 2.2's accessible authentication criterion affects:
- CAPTCHA implementations
- Password requirements
- Multi-factor authentication
- Biometric alternatives
Ensure authentication doesn't require cognitive function tests without alternatives.
The Scalable Strategy
Regardless of framework, the same strategy applies.
Build Accessible Design System
Create accessible versions of common components:
+---------------+---------------------------------------------------+
| Component | Accessibility Built In |
+---------------+---------------------------------------------------+
| Button | Accessible name required, keyboard activation |
+---------------+---------------------------------------------------+
| Input | Label association required, error handling |
+---------------+---------------------------------------------------+
| Modal | Focus trap, escape handling, focus return |
+---------------+---------------------------------------------------+
| Menu | Keyboard navigation, ARIA states |
+---------------+---------------------------------------------------+
| Tabs | Tab/panel association, arrow keys |
+---------------+---------------------------------------------------+When the design system is accessible, features built with it inherit accessibility.
Enforce with Linting and CI
+---------------+----------------------------------------------+
| Framework | Lint Tool |
+---------------+----------------------------------------------+
| React | eslint-plugin-jsx-a11y |
+---------------+----------------------------------------------+
| Vue | eslint-plugin-vuejs-accessibility |
+---------------+----------------------------------------------+
| Angular | @angular-eslint |
+---------------+----------------------------------------------+
| Svelte | Built-in compiler + eslint-plugin-svelte |
+---------------+----------------------------------------------+Add axe-core integration tests for runtime validation.
Monitor Production
Content changes and third-party updates happen post-deploy. Monitor production templates for drift regardless of framework.
Prioritize Source Code Remediation
When issues are found, fix them in source code with tests that prevent recurrence. This applies identically across all frameworks.
Framework Selection Is Not Strategy
A common misconception: choosing the "right" framework solves accessibility.
What Framework Choice Doesn't Provide
- Automatic accessible components
- Guaranteed screen reader support
- Focus management without implementation
- Compliance by default
What Framework Choice Does Affect
+----------------------------+-----------------------------------+
| Factor | Framework Impact |
+----------------------------+-----------------------------------+
| Lint tool availability | Different tools per framework |
+----------------------------+-----------------------------------+
| Testing integration | Different test libraries |
+----------------------------+-----------------------------------+
| Community patterns | Different ecosystem maturity |
+----------------------------+-----------------------------------+
| Documentation quality | Varies by framework |
+----------------------------+-----------------------------------+Procurement Sidebar
When evaluating frameworks for accessibility, ask:
- Does the ecosystem include lint rules?
- Are there accessible component libraries?
- Does documentation address accessibility?
- Do routing tools support announcements?
- Is there a testing story for accessibility?
Framework choice matters—but it's not the deciding factor in whether your application is accessible.
FAQ
Which framework is most accessible?
None is inherently more accessible. All major frameworks (React, Vue, Angular, Svelte) can produce accessible applications when used correctly. They can also produce inaccessible applications when used carelessly. Framework choice affects tooling and patterns available, but the fundamentals are the same across all of them.
Do I need framework-specific accessibility knowledge?
Some. You need to know: how your framework handles routing and announcements, what lint tools are available, how to manage focus in your framework's lifecycle, and how to test rendered output. But most accessibility knowledge is framework-agnostic—semantic HTML, ARIA patterns, keyboard behavior apply everywhere.
Should I use a component library or build my own?
For common patterns (modals, menus, tabs), use established libraries that have solved accessibility (Radix UI, Headless UI, Angular CDK). Building these correctly is complex. For custom needs, follow ARIA APG patterns exactly. Don't improvise accessible interaction patterns.
How do I handle accessibility in SSR vs CSR?
Server-side rendering (SSR) and client-side rendering (CSR) have different accessibility concerns. SSR provides initial accessible content; ensure hydration doesn't break it. CSR requires route announcements since page loads don't happen. Both need focus management after navigation. Test in both rendering modes.
What about web components and accessibility?
Web components (custom elements) have the same requirements as framework components: semantic HTML, proper ARIA, keyboard support, focus management. Shadow DOM can complicate accessibility tree exposure. Test web components with AT to verify accessibility works across the shadow boundary.
How do I keep up with framework accessibility changes?
Follow framework documentation updates. Join accessibility communities (WebAIM, A11y Slack). Monitor WCAG updates (2.2 added new criteria). Track your framework's GitHub issues for accessibility discussions. Framework accessibility improves over time—stay current.
Related Resources
Internal Links
- How Linting Changes Accessibility
- The Role of CI/CD in Accessibility
- What Developers Get Wrong About WCAG
- Accessibility as Infrastructure, Not a Feature
- What Makes Accessibility Hard to Scale
- Why Accessibility Is a Software Engineering Problem
External Sources
- React Accessibility Documentation
- Next.js Accessibility Documentation
- Angular Accessibility Guide
- Vue Accessibility Documentation
- SvelteKit Accessibility Documentation
- W3C ARIA Authoring Practices Guide
This article was written by TestParty's editorial team with AI assistance. All statistics and claims have been verified against primary sources. Last updated: January 2026.
Stay informed
Accessibility insights delivered
straight to your inbox.


Automate the software work for accessibility compliance, end-to-end.
Empowering businesses with seamless digital accessibility solutions—simple, inclusive, effective.
Book a Demo