A themeable, accessible Svelte 5 accessibility widget — floating FAB, sliding panel, built-in features, localStorage persistence, dark mode, and an easy API for adding your own features.
| Feature | Category | Effect |
|---|---|---|
| Hoher Kontrast | Sehen | Smart color inversion |
| Graustufen | Sehen | Grayscale filter |
| Animationen | Sehen | Pauses all CSS animations & transitions |
| Schriftgröße | Lesen | 4-step font size stepper (100% → 150%) |
| Links hervorheben | Lesen | Adds outline + underline to all links |
| Abstände | Lesen | Increases letter & word spacing |
| Zeilenhöhe | Lesen | Sets line-height to 1.8 |
| Dyslexie-Schrift | Lesen | Loads & applies OpenDyslexic font |
| Großer Cursor | Motorik | Replaces cursor with a large SVG pointer |
All toggle states are saved to localStorage and CSS effects are re-applied automatically on every page load.
Features planned for upcoming releases:
| Feature | Category | Description |
|---|---|---|
| 🔲 Zusätzlicher Kontrast | Sehen | Forces text to pure black/white with a contrasting background |
| 🔲 Bilder ausblenden | Sehen | Hides all images on the page |
| 🔲 Farben entsättigen | Sehen | Reduces color saturation for visual comfort |
| 🔲 ADHS-Modus | Fokus | Distraction-free browsing, hides decorative elements |
| 🔲 Screenreader-Hinweise | Navigation | Visual indicators for screen reader landmarks |
Want a feature sooner? Open an issue or add it yourself — it's just one file in
src/lib/features/.
npm install github:mow09/svelte-accessibility-widget
Then install the peer dependencies if you haven't already:
npm install @lucide/svelte
Peer dependencies:
svelte ^5.0.0,@lucide/svelte ^1.7.0,tailwindcss ^4.0.0
The widget uses Tailwind CSS utility classes. Because @tailwindcss/vite skips node_modules by default, you need to add one line to your app's CSS file before @import 'tailwindcss':
@source "./node_modules/svelte-accessibility-widget/dist";
@import 'tailwindcss';
The path is relative to your CSS file. Adjust
./node_modules/...if your CSS lives in a subdirectory (e.g.../../node_modules/...).
Place the widget in your src/routes/+layout.svelte so it appears on every page:
<script>
import { AccessibilityWidget } from 'svelte-accessibility-widget';
</script>
<AccessibilityWidget theme="indigo" position="bottom-right" />
| Prop | Type | Default | Description |
|---|---|---|---|
theme |
ThemePreset | Partial<ThemeConfig> |
'indigo' |
Color preset or custom theme object |
position |
'bottom-right' | 'bottom-left' |
'bottom-right' |
FAB position |
darkMode |
boolean | undefined |
undefined |
Force dark/light or auto-detect |
persist |
boolean |
true |
Save toggle states to localStorage |
showBranding |
boolean |
false |
Show "Powered by" footer |
labels |
Labels |
German defaults | Override any UI string |
features |
FeatureConfig[] |
[] |
Additional features to show in the panel |
'indigo' · 'violet' · 'emerald' · 'rose' · 'amber' · 'slate'
<AccessibilityWidget theme="emerald" />
<AccessibilityWidget
theme={{
primary: '#0ea5e9',
primaryHover: '#0284c7',
primaryText: '#ffffff',
background: '#ffffff',
surface: '#f0f9ff',
text: '#0c4a6e',
border: '#bae6fd',
muted: '#64748b'
}}
/>
Defaults are German. Override any string:
<AccessibilityWidget
labels={{
title: 'Accessibility',
subtitle: 'Adjust the display to your needs',
close: 'Close',
reset: 'Reset all',
hideToolbar: 'Hide toolbar'
}}
/>
css stringThe simplest way. The CSS is injected when the toggle is on and removed when off. State persists across reloads.
<script>
import { AccessibilityWidget } from 'svelte-accessibility-widget';
import { Focus } from '@lucide/svelte';
</script>
<AccessibilityWidget
features={[
{
id: 'focus-highlight',
label: 'Fokus hervorheben',
category: 'Sehen',
size: 'sm',
icon: Focus,
css: `:focus { outline: 3px solid orange !important; outline-offset: 3px !important; }`
}
]}
/>
Features are automatically grouped by category. A new category string creates a new section heading.
{#snippet extra()}For features that need sliders, steppers, or any custom Svelte component:
<AccessibilityWidget>
{#snippet extra()}
<!-- your fully custom component here -->
{/snippet}
</AccessibilityWidget>
<AccessibilityWidget showBranding={true}>
{#snippet branding()}
<a href="https://yoursite.com">Barrierefreiheit by YourBrand</a>
{/snippet}
</AccessibilityWidget>
FeatureConfig typeinterface FeatureConfig {
id: string;
label: string;
description?: string;
icon?: Component; // any Lucide icon component
category?: string; // groups features under a section heading
size?: 'sm' | 'md' | 'lg'; // 'sm' = compact card (default), 'md'/'lg' = full-width row
css?: string; // CSS injected when the toggle is active
}
import {
// Main component
AccessibilityWidget,
// Primitive components (for custom feature UIs)
FeatureCard, // compact icon + label toggle card (sm)
FeatureRow, // full-width icon + label + toggle row (md/lg)
// Built-in feature components
HighContrast,
Grayscale,
PauseAnimations,
FontSize,
HighlightLinks,
TextSpacing,
LineHeight,
DyslexiaFont,
BigCursor,
// Theme utilities
presets, // record of all ThemeConfig presets
resolveTheme, // resolveTheme(preset, isDark) → ThemeConfig
// CSS utility
injectStyle, // injectStyle(id, css) — idempotent style tag injection
removeStyle, // removeStyle(id) — removes injected style tag
} from 'svelte-accessibility-widget';
$state, $derived, $props, snippets)npm install
npm run dev # library demo at localhost:5173
npm run check # TypeScript + Svelte diagnostics
npm run build # build the library
Everything in src/lib/ is the library. svelte-demo/ is a standalone SvelteKit app that installs the widget as a consumer would — run it with:
cd svelte-demo && npm install && npm run dev