Accessibility for Svelte apps.
Svelte ships built-in a11y warnings at compile time — the best baseline of any major framework. The patterns to make use of them and the workflows for what compile-time warnings cannot catch.
What goes wrong in Svelte projects.
Ignoring or suppressing compiler a11y warnings
Svelte's compiler emits warnings for missing alt, click events on non-interactive elements, autofocus, and several other a11y problems. Teams sometimes wrap them in `<!-- svelte-ignore -->` rather than fix. Audit your suppressed warnings.
Transitions delaying aria-live announcements
Svelte `transition:fade` etc. delay DOM mutations relative to screen readers reading the aria-live region. For status/alert messages, prefer instant visibility over animated entry.
Store updates without binding to aria attributes
Svelte stores update reactively but reactive aria attributes need explicit `bind:` or `aria-busy={$loading}` template syntax. Easy to miss in complex components.
Slot content losing semantic context
Generic `<Container>` components with `<slot>` can drop the semantic role expected by accessibility tooling. If the container should be a `<section>` or `<nav>` for screen readers, render it explicitly.
SvelteKit page navigation without focus management
Like other SPAs, SvelteKit client-side route changes do not announce the new page. Use `afterNavigate` to update the page title and focus the main heading.
Form actions without aria-live error feedback
SvelteKit form actions return errors via `$page.form` — these need rendering inside an aria-live region for screen readers to announce.
The Svelte accessibility stack we recommend.
Built-in compiler warnings
Free, on by default, comprehensive baseline. The compiler catches missing alt, autofocus, click without keyboard, missing role for interactive elements. Don't suppress without fixing.
eslint-plugin-svelte (a11y rules)
npm i eslint-plugin-svelteLint rules on top of compiler warnings. Especially useful in CI to enforce no `svelte-ignore a11y-*` comments are added.
axe-core via vitest-axe or playwright-axe
npm i @axe-core/playwrightRuntime accessibility tests. Vitest + axe for component tests; Playwright + axe for e2e.
svelte-headlessui
npm i svelte-headlessuiSvelte port of Headless UI primitives. Accessible Dialog, Menu, Listbox, Combobox.
bits-ui
npm i bits-uiHeadless, accessible Svelte primitives. Larger surface than svelte-headlessui, good fit for design systems.
Step-by-step for a Svelte accessibility audit.
- 1
Audit suppressed a11y warnings
grep for `<!-- svelte-ignore a11y` across your repo. Each suppression is a bug to file (or fix immediately).
- 2
Add eslint-plugin-svelte to CI
Block PRs that add new a11y warning suppressions. Existing ones triaged on a sprint basis.
- 3
Use built-in primitives or bits-ui
Build modals, menus, listboxes from bits-ui or svelte-headlessui rather than hand-rolling. Focus management is the recurring hard part — don't reinvent it.
- 4
Add @axe-core/playwright in e2e
Automated WCAG check against each route. Block deploys on critical/serious violations.
- 5
AccessProof external scan
Scan the deployed SvelteKit app post-deploy. Catches SSR-vs-CSR differences and real-network behavior.
Run a WCAG audit on your Svelte site in 42 seconds.
External scan — no JS injected into your app
WCAG 2.2 + Section 508 + EN 301 549 in one pass
Court-ready PDF with element selectors
CI/CD gate — block deploys on regression
Works with Svelte on any hosting (Vercel, Netlify, Fly, self-hosted)
Free plan — 1 site, monthly scan
Svelte-specific questions.
Are Svelte's compile-time a11y warnings comprehensive?
They cover the most common static issues (missing alt, click without keyboard, autofocus, missing role on click handlers, label missing for control). They cannot catch dynamic issues (focus management on modal open, aria-live announcements, color contrast). Use them as a baseline; combine with runtime axe-core and manual testing.
Should I upgrade to Svelte 5 (runes) for accessibility?
Runes change the reactivity model but not accessibility fundamentals. The same a11y warnings apply, the same DOM is emitted. There's no specific accessibility win or loss from migrating; do it for the developer experience or new feature reasons.
How does SvelteKit compare to Next.js for accessibility?
Svelte ships better static a11y catches at compile time. Next.js has a larger ecosystem of accessibility libraries (react-aria-components especially). Both require manual focus management on route change. Both can be built accessibly. Pick based on developer preference, not a11y.
How do I test focus management in Svelte component tests?
Vitest + @testing-library/svelte + @testing-library/user-event. `await user.tab()`, assert `document.activeElement`. Same pattern as React tests.