Registry / web-framework / focus-trap

focus-trap

JSON →
library8.0.1jsnpmunverified

focus-trap is a vanilla JavaScript library designed to trap keyboard focus within a specified DOM node, essential for building accessible UI components like modals, dialogs, and sidebars. It ensures that users navigating with keyboard (Tab, Shift+Tab) or screen readers cannot escape the designated area, enhancing accessibility. The current stable version is 8.0.1, with releases occurring as needed for bug fixes (patch), new features (minor), and breaking changes (major). Key differentiators include its lightweight, framework-agnostic nature, robust handling of nested traps (pausing/unpausing), and its reliance on the well-maintained `tabbable` library for determining focusable elements. It handles initial focus, tabbing within the trap, blocking clicks outside, and restoring focus on deactivation. It explicitly supports modern desktop browsers and offers UMD builds for environments without bundlers.

npm install focus-trap
INSTALL
IMPORT
SIG · FOCUS-TRAP
F
focus-trap
web-frameworkjavascriptv8.0.1
Install
Import
Disk
Pass rate
0/ 6
Env Coverage0 / 6
glibc
1822
musl
1822
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
node 18226 runs
build_error
glibc
node 18226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

createFocusTrap
import { createFocusTrap } from 'focus-trap';
import createFocusTrap from 'focus-trap';
This library uses named exports. There is no default export for the primary function.
FocusTrap
import type { FocusTrap } from 'focus-trap';
Import the type definition for the FocusTrap instance if working with TypeScript.
createFocusTrap (CommonJS)
const { createFocusTrap } = require('focus-trap');
const createFocusTrap = require('focus-trap');
While CommonJS `require` works, the primary export is named. ESM imports are preferred in modern Node.js and bundled environments.
createFocusTrap (UMD)
<!-- Include tabbable first --> <script src="https://unpkg.com/tabbable/dist/index.umd.js"></script> <script src="https://unpkg.com/focus-trap/dist/focus-trap.umd.js"></script> <script> const { createFocusTrap } = window.FocusTrap; </script>
When using the UMD build from unpkg, `tabbable` must be included separately and *before* focus-trap. The library exposes its named exports on `window.FocusTrap`.

Demonstrates creating, activating, and deactivating a focus trap for a modal dialog, including managing visibility and returning focus.

import { createFocusTrap } from 'focus-trap'; const modalElement = document.getElementById('my-modal'); const openButton = document.getElementById('open-modal-button'); const closeButton = document.getElementById('close-modal-button'); let focusTrapInstance: ReturnType<typeof createFocusTrap> | null = null; function openModal() { if (modalElement) { modalElement.style.display = 'block'; focusTrapInstance = createFocusTrap(modalElement, { onDeactivate: () => { if (modalElement) modalElement.style.display = 'none'; openButton?.focus(); // Return focus to the element that opened the modal }, initialFocus: closeButton || undefined, // Optionally focus the close button first }); focusTrapInstance.activate(); } } function closeModal() { if (focusTrapInstance) { focusTrapInstance.deactivate(); focusTrapInstance = null; } } openButton?.addEventListener('click', openModal); closeButton?.addEventListener('click', closeModal); // Example: simulate opening a modal after a delay setTimeout(openModal, 1000);
Debug
Known issues
breakingThe `onPostActivate()` callback now correctly executes *after* the initial focus node has received focus and the trap is fully activated. Previously, it would fire prematurely. This aligns the behavior with the intended purpose of `onPostActivate()`.
fix
Review existing `onPostActivate()` implementations. If you relied on the previous, incorrect timing, you may need to adjust your logic or use `onActivate()` if you need a callback before focus is set.
affects: >=8.0.0
gotchaIn Safari, the default browser settings prevent tabbing through all elements on a webpage. This significantly impacts how `focus-trap` determines and cycles through tabbable elements, potentially causing traps to not work as expected.
fix
Users and developers must enable 'Preferences > Advanced > Press Tab to highlight each item on a webpage' in Safari settings for focus traps to function correctly.
affects: >=1.0.0
deprecatedSupport for Internet Explorer (all versions) has been officially dropped due to Microsoft's end-of-life for IE. The library no longer guarantees functionality or provides fixes for IE-specific issues.
fix
Avoid using `focus-trap` in projects requiring IE compatibility. Consider polyfills or alternative strategies for legacy browser support if absolutely necessary, but it's generally recommended to drop IE support.
affects: >=7.6.4
gotchaWhen using the UMD build (`dist/focus-trap.umd.js`) directly in the browser without a module bundler, the `tabbable` dependency is *not* bundled with `focus-trap`. It must be included separately and loaded *before* `focus-trap`.
fix
Ensure that `<script src="https://unpkg.com/tabbable/dist/index.umd.js"></script>` is placed in your HTML *before* `<script src="https://unpkg.com/focus-trap/dist/focus-trap.umd.js"></script>`.
affects: >=1.0.0
Errors
Common errors & fixes
TypeError: Cannot read properties of undefined (reading 'activate')
`createFocusTrap` was called with a non-existent or null DOM element, resulting in `undefined` being returned. Subsequently, `undefined.activate()` throws an error.
fix
Ensure the DOM element passed to `createFocusTrap` exists and is a valid `HTMLElement`. Check for `null` or `undefined` returns from `document.getElementById` or `document.querySelector`.
Focus trap is not working as expected (e.g., focus escapes the modal, tabbing order is incorrect, clicks outside are not blocked).
This is often due to the Safari 'Press Tab to highlight each item on a webpage' setting being disabled, or incorrectly configured `initialFocus` options, or elements within the trap not being correctly identified as tabbable by `tabbable`.
fix
For Safari, ensure the specific setting is enabled. Verify that your elements are natively tabbable or correctly marked with `tabindex`. Review the `tabbable` library documentation for details on what elements are considered tabbable. Also, check for CSS properties like `display: none` or `visibility: hidden` on the trap's container or its tabbable children.
ReferenceError: FocusTrap is not defined
Occurs when using the UMD build (e.g., from unpkg) but trying to access `FocusTrap` globally without it being loaded, or trying to destructure `createFocusTrap` when only `window.FocusTrap` is available.
fix
Ensure the UMD script for `focus-trap` is properly loaded. When loaded via UMD, the exports are typically available under `window.FocusTrap`, so you would access `window.FocusTrap.createFocusTrap`.
Upgrade
Version history
8.0.1latest on npm
Audit
Dependencies
tabbablerequiredUsed internally to determine the order of focusable elements within the trap, crucial for proper keyboard navigation.
Agent activity
19 hits · last 30 days
node
16
Amazon
1
OpenAI (training)
1
Resources
focus-trap — npm install focus-trap · libregistry