Documentation
Install, configure, and integrate. If you would rather read the source, the whole widget is one commented file.
Install
Paste one tag before the closing body tag. Nothing else is required — no build step, no package manager, no framework.
<script src="https://a11y.elixtechs.com/a11y/v1/loader.js?k=YOUR_SITE_KEY" async></script>
One site, full features, no card. It exists so you can put the widget on a real page and see the analytics fill in.
Self-hosting
<script src="/assets/a11y/accessibility.js"
data-a11y-auto
data-a11y-lang="ar"
data-a11y-fonts="/assets/a11y/fonts/"></script>
Configuration options
Set these in the portal per site, or pass them to the initialiser directly if you are self-hosting.
| Option | Default | Notes |
|---|---|---|
position |
bottom-right |
Logical: right means the inline-end side, so it flips in RTL. |
lang |
auto |
Resolves config → <html lang> → navigator.language → en. |
translations |
null |
Merged over the built-ins, so a partial table falls back to the shipped strings. |
fontsPath |
next to the script | Where the woff2 files live. |
shortcut |
alt+shift+a |
Matched by physical key too, so it survives a keyboard layout change. |
features |
null |
Allowlist of feature ids. null means all. |
exclude |
null |
Blocklist, applied after the allowlist. |
colorFilterTarget |
html |
Leave this alone. See the trade-offs below. |
autoApplyOsPreferences |
false |
When false, OS preferences are offered rather than imposed. |
statementUrl |
null |
Optional link in the panel footer. |
zIndex |
2147483000 |
Below max int32, so a host can still deliberately go above it. |
JavaScript API
A11y.init(options)
A11y.get() // whole state
A11y.get('fontSize') // one value
A11y.set('fontSize', 1.5)
A11y.patch({ contrast: 'high', highlightLinks: true })
A11y.applyProfile('dyslexia')
A11y.reset()
A11y.open() / .close() / .toggle()
A11y.setLanguage('ar')
A11y.announce('message') // into the panel's live region
A11y.env() // detected OS / browser / OS preferences
A11y.features() / A11y.profiles()
A11y.destroy() // removes every trace
Events
document.addEventListener('a11y:ready', e => e.detail); // { state, env }
document.addEventListener('a11y:change', e => e.detail); // { id, value, state }
document.addEventListener('a11y:open', e => e.detail); // { state }
document.addEventListener('a11y:close', e => e.detail); // { state }
A batch change — a profile or a reset — reports id as
'*' with an array of the ids that changed.
Known trade-offs
Documented because a surprise in production is worse than a caveat in the docs.
Colour filters and fixed positioning
A filtered element becomes the containing block for its fixed-position descendants, which makes fixed headers scroll away. The root element is exempt, because a filter on it applies to the canvas and creates no containing block. This is why the filter target defaults to the root, and why changing it is the risky move rather than the safe one.
Text scaling cannot fix every layout
A container with a fixed height and hidden overflow will clip when text grows. The widget scales each element to an absolute pixel value rather than setting a root font size, because the root-font-size approach silently does nothing on a pixel-based site — which is most sites.
Distraction removal is conservative
Matching class names loosely for advertisements also hits the header, the badge, the loading indicator and the download button. Only whole-word matches are used, and everything is reversible.
Browser support
Chrome and Edge 90 and later, Firefox 90 and later, Safari 15.4 and later. Older browsers lose isolation strength or a cosmetic detail, never function.
What this is, and what it is not
This widget is an aid layered on top of a site. It helps a visitor adapt a page to how they read, and it repairs a defined set of common defects. It does not make a site WCAG, ADA or EN 301 549 conformant, and we do not sell it as though it does. Underlying markup defects remain defects: the widget can add a missing label, but it cannot know what an unlabelled icon means, cannot fix a wrong heading order, and cannot make a keyboard trap disappear.