Skip to content

Accessibility modes

Let people see the page their way

Contrast schemes, color-vision filters, text spacing, reading aids, motion and interaction aids. Each one is a data-a11y-* attribute on <html> or any container, works in all 21 themes and in custom brand themes, mirrors in right-to-left languages, and is available as a ready-made settings panel in React, Vue, Svelte, Angular and Astro.

See every mode

Color schemes

Each card below is the same interface with one scheme applied to just that card.

High contrast hc

Body text, a link and a muted note.

Saved Failed
Yellow on black yellow-black

Body text, a link and a muted note.

Saved Failed
Black on yellow black-yellow

Body text, a link and a muted note.

Saved Failed
White on black white-black

Body text, a link and a muted note.

Saved Failed
Black on white black-white

Body text, a link and a muted note.

Saved Failed
Grayscale gray

Body text, a link and a muted note.

Saved Failed
Inverted invert

Body text, a link and a muted note.

Saved Failed

Try it on part of a page

This panel is scoped: it writes its attributes to the card below only and does not save anything. The panel in the site header changes the whole site and remembers your choice.

Quarterly report

Revenue grew 12% this quarter. Read the full report or download the summary. Most of the growth came from returning customers, who now make up more than half of all orders.

Support response times fell to under two hours, and satisfaction scores reached their highest level this year.

On track 2 risks

Every mode

ModeAttributeValuesWhat it doesWCAG
Color schemedata-a11y-contrasthc · yellow-black · black-yellow · white-black · black-white · gray · invertComplete token palettes (!important), so contrast is exact. Gray adds a grayscale filter for images; invert re-inverts photos and video.1.4.3, 1.4.6, 1.4.11
Color visiondata-a11y-color-filterprotanopia · deuteranopia · tritanopia · achromatopsiaDaltonization filters (inline SVG feColorMatrix) move hues you cannot tell apart into ones you can.1.4.1
Patternsdata-a11y-patterns(present)Charts add hatching, dashes and markers. On automatically in gray, hc and achromatopsia.1.4.1
Saturationdata-a11y-saturationlow · highLow desaturates the page; high only boosts images and charts, so text contrast never drops.
Text sizedata-a11y-font-scale + --pl-user-font-scale0.9 – 2Scales every type token and the page text, without zooming the layout.1.4.4
Line / letter / word / paragraph spacingdata-a11y-line-height · -letter-spacing · -word-spacing · -paragraph-spacingwide · wider"wider" meets or exceeds the WCAG text-spacing values; components reflow without clipping. Arabic keeps letter-spacing at 0 so letters stay joined.1.4.12
Readable fontdata-a11y-fontreadableAtkinson Hyperlegible (self-hosted, SIL OFL), with an Arabic fallback.
Align to startdata-a11y-text-alignstartNo justified or centered paragraphs; start is right in RTL.1.4.8
Linksdata-a11y-linksunderline · highlightUnderline every link, or underline and highlight it.1.4.1
Focus indicatordata-a11y-focuslarge4px outline plus a wide halo on everything focusable.2.4.7, 2.4.13
Big cursordata-a11y-cursorlarge48px SVG cursors (arrow, hand, text) with a light outline that reads on any background.
Reading guide / maskdata-a11y-reading-guide · data-a11y-reading-mask(present)A band that follows the pointer and keyboard focus, or a mask that dims everything else.
Motiondata-a11y-motionfull · reduce · offFull keeps animations on even when the device asks to reduce motion; reduce matches prefers-reduced-motion; off stops every animation and transition and pauses autoplaying media. The animated theme switch follows the same setting.2.2.2, 2.3.3
Themedata-theme · data-theme-preset · data-accentsystem · light · dark · hc; 10 presets; 9 accents; any brand colorThe panel’s Theme group: mode, named color themes, accent and your own color (createTheme keeps it WCAG AA). Changes reveal in a circle from the control you used.1.4.3, 1.4.11
Soundpl-sound (storage)on · off; soft · crisp · playful · minimalInterface sounds through the Pelagic sound engine. The group appears when the page has a sound engine.1.4.2
Decorative imagesdata-a11y-imageshideHides images with empty alt text, presentation images, illustrations and [data-decorative].
Large targetsdata-a11y-targetslargeEvery control at least 44 × 44 px with any pointer.2.5.5, 2.5.8

Verified contrast

scripts/check-contrast.mjs checks all 40 text, control and focus pairs for every scheme, the inverted and low-saturation renderings of all 21 themes, and a sample of custom brand themes, on every build. Lowest ratio per scheme:

SchemeColorsLowest text pair (needs 4.5)Lowest UI pair (needs 3)
yellow-black #ffff00 on #000000 14.73:1 18.61:1
black-yellow #000000 on #ffff00 12.98:1 18.10:1
white-black #ffffff on #000000 14.45:1 19.91:1
black-white #000000 on #ffffff 12.63:1 19.43:1
gray #1a1a1a on #ffffff 6.56:1 3.88:1
gray-dark #ededed on #141414 7.03:1 4.55:1

Use it

JavaScript

import {
  applyA11yPrefs, loadA11yPrefs, saveA11yPrefs, resetA11yPrefs, watchSystemPrefs,
} from '@pelagic-ui/core/a11y-prefs';

// Restore what the user chose last time, then apply it to <html> (or any container).
const prefs = applyA11yPrefs(loadA11yPrefs());

// Change one thing.
saveA11yPrefs(applyA11yPrefs({ ...prefs, contrast: 'yellow-black', fontScale: 1.5 }));

// Follow the OS: reduced motion, contrast, dark mode, forced colors.
const stop = watchSystemPrefs((os) => console.log(os.reducedMotion, os.contrast));

The panel

// React
import { AccessibilityPanel } from '@pelagic-ui/react';
<AccessibilityPanel locale="ar" onChange={(prefs, change) => track(change)} />

// Vue:     <AccessibilityPanel v-model="prefs" trigger="inline" />
// Svelte:  <AccessibilityPanel bind:prefs bind:open />
// Angular: <pl-accessibility-panel [(prefs)]="prefs" locale="ar" />
// Astro:   <AccessibilityPanel trigger="inline" locale={lang} />
// HTML:    root.innerHTML = renderA11yPanelHTML({ locale: 'en' }); mountA11yPanel(root.firstElementChild);

Without JavaScript

<!-- No JavaScript needed for the CSS modes: set the attributes yourself (or server-side). -->
<html data-a11y-contrast="black-yellow" data-a11y-line-height="wider" data-a11y-links="underline">
<section data-a11y-contrast="gray">Scoped to one part of the page</section>

Search Pelagic UI