A comprehensive accessibility overlay for any RSL-powered website
The RSL Accessibility Widget provides users with extensive control over how they experience your website. It supports text adjustments, visual modifications, navigation aids, and motion preferences - all saved to localStorage for persistent settings.
Add the CSS and JavaScript files to your HTML:
<!-- In your <head> -->
<link rel="stylesheet" href="styles/accessibility-widget.css" />
<!-- Before closing </body> -->
<script src="javascript/accessibility-widget.js"></script>
| Shortcut | Action |
|---|---|
| Alt + A | Toggle accessibility panel open/closed |
| Escape | Close the panel (when open) |
| Tab | Navigate through controls |
| Enter / Space | Activate toggle buttons |
| Cmd + 0 (Mac) / Ctrl + 0 (Win) | Reset page zoom to 100% |
The widget exposes a public API through window.RSL.AccessibilityWidget:
| Method | Description |
|---|---|
init() |
Initialize the widget (called automatically) |
open() |
Open the settings panel |
close() |
Close the settings panel |
toggle() |
Toggle the panel open/closed |
reset() |
Reset all settings to defaults |
getSetting(key) |
Get the current value of a setting |
setSetting(key, value) |
Programmatically set a setting value |
getPosition() |
Get the current position of the floating button |
setPosition(position) |
Move the button to a new position (bottom-left, bottom-right, top-left, top-right) |
getValidPositions() |
Get an array of valid position values |
ttsPlay() |
Start reading page content aloud |
ttsPauseResume() |
Pause or resume speech |
ttsStop() |
Stop reading completely |
ttsReadElement(element) |
Read a specific HTML element aloud |
ttsSupported() |
Check if browser supports Text-to-Speech |
// Open the panel programmatically
RSL.AccessibilityWidget.open();
// Enable high contrast mode
RSL.AccessibilityWidget.setSetting('highContrast', true);
// Get current font size
const fontSize = RSL.AccessibilityWidget.getSetting('fontSize');
console.log('Font size:', fontSize + '%');
// Reset all settings
RSL.AccessibilityWidget.reset();
// Move button to bottom-right corner
RSL.AccessibilityWidget.setPosition('bottom-right');
// Get current position
const pos = RSL.AccessibilityWidget.getPosition();
console.log('Button position:', pos);
// Get all valid positions
const positions = RSL.AccessibilityWidget.getValidPositions();
// ['bottom-left', 'bottom-right', 'top-left', 'top-right']
// ---- Text-to-Speech API ----
// Enable TTS mode (allows click-to-read)
RSL.AccessibilityWidget.setSetting('ttsEnabled', true);
// Read the entire page content
RSL.AccessibilityWidget.ttsPlay();
// Pause/resume reading
RSL.AccessibilityWidget.ttsPauseResume();
// Stop reading
RSL.AccessibilityWidget.ttsStop();
// Read a specific element
const paragraph = document.querySelector('p');
RSL.AccessibilityWidget.ttsReadElement(paragraph);
// Check if TTS is supported
if (RSL.AccessibilityWidget.ttsSupported()) {
console.log('Text-to-Speech is available!');
}
| Setting | Type | Default | Description |
|---|---|---|---|
fontSize |
Number | 100 | Font size percentage (50-200) |
lineHeight |
Number | 100 | Line height percentage (100-200) |
letterSpacing |
Number | 0 | Letter spacing in pixels (0-10) |
wordSpacing |
Number | 0 | Word spacing in pixels (0-20) |
fontFamily |
String | 'default' | Font family (default, arial, verdana, georgia, times, courier, opendyslexic) |
textAlign |
String | 'default' | Text alignment (default, left, center, right) |
| Setting | Type | Default | Description |
|---|---|---|---|
highContrast |
Boolean | false | Enable high contrast mode |
invertColors |
Boolean | false | Invert page colors |
grayscale |
Boolean | false | Convert to grayscale |
lowSaturation |
Boolean | false | Reduce color saturation |
highSaturation |
Boolean | false | Increase color saturation |
highlightLinks |
Boolean | false | Highlight all links |
highlightHeadings |
Boolean | false | Highlight all headings |
| Setting | Type | Default | Description |
|---|---|---|---|
bigCursor |
Boolean | false | Enable large cursor |
readingGuide |
Boolean | false | Show reading guide line |
focusIndicator |
Boolean | false | Enhanced focus indicators |
readingMask |
Boolean | false | Show reading mask overlay |
| Setting | Type | Default | Description |
|---|---|---|---|
stopAnimations |
Boolean | false | Stop all CSS animations/transitions |
hideImages |
Boolean | false | Reduce image visibility |
| Setting | Type | Default | Description |
|---|---|---|---|
ttsEnabled |
Boolean | false | Enable click-to-read mode |
ttsRate |
Number | 1.0 | Speech rate (0.5 to 2.0) |
| Setting | Type | Default | Description |
|---|---|---|---|
pageZoom |
Number | 100 | Page zoom percentage (100 to 400) |
The widget appearance can be fully customized to match your brand using CSS variables:
Override these CSS variables to change the widget's colors:
:root {
/* Primary brand colors */
--rsl-a11y-primary: #667eea;
--rsl-a11y-secondary: #764ba2;
/* Gradient customization */
--rsl-a11y-button-gradient: linear-gradient(135deg, var(--rsl-a11y-primary) 0%, var(--rsl-a11y-secondary) 100%);
--rsl-a11y-header-gradient: linear-gradient(135deg, var(--rsl-a11y-primary) 0%, var(--rsl-a11y-secondary) 100%);
--rsl-a11y-toggle-gradient: linear-gradient(135deg, var(--rsl-a11y-primary) 0%, var(--rsl-a11y-secondary) 100%);
/* Text colors */
--rsl-a11y-header-text: #ffffff;
--rsl-a11y-button-icon: #ffffff;
/* Panel colors */
--rsl-a11y-panel-bg: #ffffff;
--rsl-a11y-panel-border: #e0e0e0;
--rsl-a11y-text: #333333;
--rsl-a11y-text-muted: #666666;
--rsl-a11y-hover-bg: #f5f5f5;
--rsl-a11y-toggle-bg: #f8f9fa;
}
/* Match your brand with custom colors */
:root {
--rsl-a11y-primary: #ff6b35;
--rsl-a11y-secondary: #e85d04;
--rsl-a11y-button-gradient: linear-gradient(135deg, #ff6b35 0%, #e85d04 100%);
--rsl-a11y-header-gradient: linear-gradient(135deg, #ff6b35 0%, #e85d04 100%);
--rsl-a11y-toggle-gradient: linear-gradient(135deg, #ff6b35 0%, #e85d04 100%);
}
The floating accessibility button can be placed in any of the four corners of the screen. Set the position using the data-position attribute on the script tag:
<!-- Default: bottom-left -->
<script src="javascript/accessibility-widget.js"></script>
<!-- Bottom-right corner -->
<script src="javascript/accessibility-widget.js" data-position="bottom-right"></script>
<!-- Top-left corner -->
<script src="javascript/accessibility-widget.js" data-position="top-left"></script>
<!-- Top-right corner -->
<script src="javascript/accessibility-widget.js" data-position="top-right"></script>
| Position | Description |
|---|---|
bottom-left |
Default position - button in bottom-left corner |
bottom-right |
Button in bottom-right corner |
top-left |
Button in top-left corner |
top-right |
Button in top-right corner |
For quick color customization without CSS, you can pass colors directly via data attributes on the script tag. This is especially useful for templates that need to match brand colors:
<!-- Custom brand colors via data attributes -->
<script src="javascript/accessibility-widget.js"
data-primary="#8B1538"
data-secondary="#6B1028">
</script>
<!-- With custom icon and text colors -->
<script src="javascript/accessibility-widget.js"
data-primary="#ff6b35"
data-secondary="#e85d04"
data-button-icon="#ffffff"
data-header-text="#ffffff">
</script>
<!-- Combine with position -->
<script src="javascript/accessibility-widget.js"
data-position="bottom-right"
data-primary="#2563eb"
data-secondary="#1e40af">
</script>
| Data Attribute | Description | Default |
|---|---|---|
data-primary |
Primary brand color (used for button gradient start, active states) | #667eea |
data-secondary |
Secondary brand color (used for gradient end). Falls back to primary if not set. | #764ba2 |
data-button-icon |
Color of the icon inside the floating accessibility button | #ffffff |
data-header-text |
Color of text in the panel header | #ffffff |
<!-- Maroon and gold school colors -->
<script src="javascript/accessibility-widget.js"
data-position="bottom-right"
data-primary="#8B1538"
data-secondary="#6B1028">
</script>
data-theme="dark" is set on the HTML element. Dark mode CSS variables are included by default.
The widget itself is fully accessible:
aria-pressedprefers-reduced-motion media queryThe accessibility widget works seamlessly with other RSL components:
View examples.html for comprehensive demos
Test features in playground.html
Browse all RSL components