Lightweight, accessible UI component library with full ARIA support
Collection of fully accessible UI components for modern web applications. Zero dependencies, vanilla JavaScript.
5 ready components (v1.0) + 6 in roadmap (v1.1+)
All components are built following WAI-ARIA Authoring Practices Guide with full keyboard navigation and screen reader support.
Accessible dropdown with keyboard navigation for navigation menus, language switchers, and action menus.
Tabs with full a11y support for organizing content into separate sections.
Sliding side panel with focus trap and full a11y support for navigation and sidebars.
Modal dialog with focus trap and proper focus management for overlay interactions.
Standalone collapse toggle for show/hide functionality with ARIA support.
Accessible accordion with keyboard navigation for groups of collapsible sections.
Accessible tooltip with ARIA support and smart positioning.
Live region announcements with auto-dismiss and notification stacking.
Switch component with localStorage/preferences support and ARIA attributes.
Interactive popover with positioning and focus management for rich content.
ARIA alert component with dismissible support and various message types.
Complex ARIA pattern for search, autocomplete, and filtering with keyboard navigation.
All components follow WAI-ARIA standards
Complete keyboard navigation support
Separated core and theme CSS for easy customization
Vanilla JavaScript without external libraries
Works on all devices and screen sizes
Automatic dark mode support
<!-- Core CSS (logic) -->
<link rel="stylesheet" href="css/a11y-dropdown.core.css">
<link rel="stylesheet" href="css/a11y-tabs.core.css">
<link rel="stylesheet" href="css/a11y-offcanvas.core.css">
<link rel="stylesheet" href="css/a11y-modal.core.css">
<link rel="stylesheet" href="css/a11y-accordion.core.css">
<!-- Theme CSS (visual) -->
<link rel="stylesheet" href="css/a11y-dropdown.theme.css">
<link rel="stylesheet" href="css/a11y-tabs.theme.css">
<link rel="stylesheet" href="css/a11y-offcanvas.theme.css">
<link rel="stylesheet" href="css/a11y-modal.theme.css">
<link rel="stylesheet" href="css/a11y-accordion.theme.css">
<script src="js/a11y-dropdown.js"></script>
<script src="js/a11y-tabs.js"></script>
<script src="js/a11y-offcanvas.js"></script>
<script src="js/a11y-modal.js"></script>
<script src="js/a11y-accordion.js"></script>
<!-- Dropdown -->
<div data-dropdown>
<button data-dropdown-button>
Options
<span class="dropdown__arrow"></span>
</button>
<div data-dropdown-menu>
<button data-dropdown-item>Item 1</button>
<button data-dropdown-item>Item 2</button>
</div>
</div>
<!-- Tabs -->
<div data-tabs>
<div role="tablist" data-tabs-list>
<button data-tabs-tab>Tab 1</button>
<button data-tabs-tab>Tab 2</button>
</div>
<div data-tabs-panel>Content 1</div>
<div data-tabs-panel>Content 2</div>
</div>
<!-- Offcanvas -->
<button data-offcanvas-trigger="menu">☰ Menu</button>
<div data-offcanvas id="menu">
<div data-position="left" data-offcanvas-panel>
<div data-offcanvas-header>
<h2 data-offcanvas-title>Menu</h2>
<button data-offcanvas-close>×</button>
</div>
<div data-offcanvas-body>Content...</div>
</div>
<div data-offcanvas-backdrop></div>
</div>
<!-- Modal -->
<button data-modal-trigger="my-modal">Open Modal</button>
<div data-modal id="my-modal">
<div data-modal-dialog>
<div data-modal-header>
<h2 data-modal-title>Title</h2>
<button data-modal-close>×</button>
</div>
<div data-modal-body>Content...</div>
<div data-modal-footer>
<button data-modal-close>Close</button>
</div>
</div>
<div data-modal-backdrop></div>
</div>
<!-- Accordion -->
<div data-accordion>
<div data-accordion-item>
<button data-accordion-trigger>Section 1</button>
<div data-accordion-panel>Content 1</div>
</div>
<div data-accordion-item>
<button data-accordion-trigger>Section 2</button>
<div data-accordion-panel>Content 2</div>
</div>
</div>
Accessible Kit supports multiple initialization methods according to your needs: automatic initialization via CDN, manual initialization with callbacks, and ES6 import for module bundlers (Astro, Vite, Webpack).
When using via <script> tag, components initialize automatically:
<script src="js/a11y-dropdown.js"></script>
<!-- Dropdown automatically initializes after DOM loads -->
<script src="js/a11y-dropdown.js"></script>
<script src="js/a11y-tabs.js"></script>
<!-- Or all at once: -->
<script src="js/index.js"></script>
<script>
// Via global namespace (recommended - no collisions)
a11yKit.initAll(); // initializes all components
// Or individually
a11yKit.initDropdowns();
a11yKit.initTabs();
a11yKit.initCollapses();
a11yKit.initAccordions();
// Bootstrap style - short aliases
const dropdown = new a11yKit.Dropdown(element, options);
const modal = new a11yKit.Modal(element, options);
const collapse = new a11yKit.Collapse();
const accordion = new a11yKit.Accordion();
</script>
<script>
window.a11yKitManualInit = true;
</script>
<script src="js/a11y-dropdown.js"></script>
<script>
// Via namespace (recommended)
a11yKit.initDropdowns();
// Or directly (backwards compatible)
initDropdowns();
</script>
import { initDropdowns } from './a11y-kit/a11y-dropdown.js';
import { initTabs } from './a11y-kit/a11y-tabs.js';
initDropdowns();
initTabs();
import { Dropdown, Modal, Tabs, Collapse, Accordion } from './a11y-kit/index.js';
// Use like Bootstrap
const dropdown = new Dropdown(element, {
closeOnSelect: true,
onOpen: (instance) => { console.log('Opened!'); }
});
const collapse = new Collapse();
const accordion = new Accordion();
import * as a11yKit from './a11y-kit/index.js';
// Init functions:
a11yKit.initAll();
a11yKit.initDropdowns();
a11yKit.initCollapses();
a11yKit.initAccordions();
// Bootstrap style:
const dropdown = new a11yKit.Dropdown(element, options);
const modal = new a11yKit.Modal(element, options);
const collapse = new a11yKit.Collapse();
const accordion = new a11yKit.Accordion();
// src/layouts/Layout.astro
<script>
// Variant 1: Named imports
import { initDropdowns } from '/src/assets/js/a11y-kit/a11y-dropdown.js';
import { initTabs } from '/src/assets/js/a11y-kit/a11y-tabs.js';
initDropdowns();
initTabs();
</script>
<!-- OR -->
<script>
// Variant 2: Wildcard import
import * as a11yKit from '/src/assets/js/a11y-kit';
a11yKit.initAll(); // all at once
</script>
import { AccessibleDropdown } from './a11y-kit/a11y-dropdown.js';
const dropdown = new AccessibleDropdown(element, {
closeOnSelect: true,
onOpen: (instance) => {
console.log('Opened!');
},
onClose: (instance) => {
console.log('Closed!');
},
onSelect: (item, index) => {
console.log('Selected item:', item.textContent);
}
});
// Installation
npm install accessible-kit
// Import
import { initAll } from 'accessible-kit';
initAll();
// Or wildcard
import * as a11yKit from 'accessible-kit';
a11yKit.initDropdowns();
// Or individual components (tree-shaking)
import { initDropdowns } from 'accessible-kit/dropdown';
import { initTabs } from 'accessible-kit/tabs';
initDropdowns();
initTabs();
./a11y-kit/a11y-dropdown.js) - always works, clear and explicit./a11y-kit/a11y-dropdown) - works in most modern bundlers./a11y-kit) - works if you have index.jsinitComponentName() (Recommended)new AccessibleComponent()initAll() to initialize all componentsDetailed documentation for each component can be found in the README.md file or on the demo pages of individual components.
View on GitHub or check the Contributing Guide.