NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
npm · #1789 most downloaded on npm
Returns an array of all tabbable DOM nodes within a containing node.
Last release 3 months ago
20 Jun 2026
Ships unpredictably
gaps range from 2 weeks to 2.3 years
Nearly every release is documented
notes for 42 of 45 stable releases
Nothing withdrawn
no release was ever pulled
11 years old
50 releases · first in 2015
8e6c074 : Add support for <area> elements with an href attribute (image map hotspots),
<area> elements with an href attribute (image map hotspots),visibility: collapse as hidden, the same way visibility: hidden is already handled, so they are no longer considered tabbable or focusable. This matches browser behavior, where collapse hides an element (outside of table rows/columns) just like hidden.26a1d80 : Enable CSS selector matching for whether an element is in an inert subtree ( [inert] * ).
26a1d80: Enable CSS selector matching for whether an element is in an inert subtree ([inert] *).
This was previously disabled due to JSDOM's CSS selector engine being incompatible with this selector, and throwing all the results off. Instead, tabbable would perform manual checks for an element being in an inert subtree. The CSS selector issue appears to have been fixed in recent JSDOM versions (at least 26), so this version reintroduces the selector fast path.
One column per quarter.
fae1e50 : feat: add 'full-native' displayCheck option, utilising Element#checkVisibility
displayCheck option, utilising Element#checkVisibility18a093f : Add new getTabIndex() API which enables Focus-trap to determine tab indexes in the same way as Tabbable when necessary (see focus-trap#974 )
getTabIndex() API which enables Focus-trap to determine tab indexes in the same way as Tabbable when necessary (see focus-trap#974).b39b217 : Pin jsdom downstream dependency nwsapi to v2.2.2 while awaiting fix
97373cc : Fix JSDom not supporting HTMLElement.inert and HTMLElement.contentEditable APIs, and not supporting CSS selector ':not([inert *])' resulting
1756c90 : Add support for new inert attribute
isHidden() -> isNodeAttached() -> getRootNode() if not handled properly (focus-trap-react #905)Nothing published for this version
Nothing published for this version
Nothing published for this version
0aab1e3: Fix crash with tabbable scoped table header elements
5f40c8e: Revised and clarified official browser support (still as broad and deep as _reasonably_ possible).
displayCheck 'full' option no longer treats detached nodes as visible. Use the new 'legacy-full' option to restore old (incorrect) behavior only if you must. Ideally, make sure tabbable only runs once all nodes of interest have been attached to the document.0210a1c: fix: align with browser behaviour when a web component has a negative tabindex
320bfd1: Updated docs for displayCheck configuration.
displayCheck configuration.displayCheck=full (default setting) determining all nodes were hidden when the container is not attached to the document. In this case, tabbable will revert to a displayCheck=none mode, which is the equivalent legacy behavior. Also updated the displayCheck option docs to add warnings about this corner case for the full and non-zero-area modes. non-zero-area behaves differently in the corner case. See the docs for more info.cf1da66: Add warnings and help in documentation about running tabbable under JSDom (e.g. with Jest). JSDom is not technically supported, and 5.3.0 int
getShadowRoot option to isTabbable() and isFocusable() (docs only; no code changes necessary).685a906: Adds new Shadow DOM support (must be explicitly enabled using the new getShadowRoot option).
getShadowRoot option).
5.3.0-beta.0 and 5.3.0-beta.1 releases.getTabIndex: the tab index of <audio>, <video> and <details> was left to the browser default if explicitly set to a value that couldn't be parsed as integer, leading to inconsistent behavior across browsers. Also slightly modified the function's logic to make it more efficient. Finally added tests to cover the fix.displayCheck: "full" option (now checks for any element having no display boxes) and added test for display: "contents" property (this bug was never reported). (#592)isDisabledFromFieldset. The function wasn't checking whether the disabled <fieldset> containing node is the top-most disabled <fieldset> (#596).getShadowRoot option).
5.3.0-beta.0 and 5.3.0-beta.1 releases.getTabIndex: the tab index of <audio>, <video> and <details> was left to the browser default if explicitly set to a value that couldn't be parsed as integer, leading to inconsistent behavior across browsers. Also slightly modified the function's logic to make it more efficient. Finally added tests to cover the fix.displayCheck: "full" option (now checks for any element having no display boxes) and added test for display: "contents" property (this bug was never reported). (#592)
isDisabledFromFieldset. The function wasn't checking whether the disabled <fieldset> containing node is the top-most disabled <fieldset> (#596).Add support for setting getShadowRoot: true as an easy way to simply _enable_ shadow DOM support. This is the equivalent of setting getShadowRoot: ()
getShadowRoot: true as an easy way to simply enable shadow DOM support. This is the equivalent of setting getShadowRoot: () => false, which means tabbable will find nodes in open shadow roots only.Includes new Shadow DOM support for open shadows by default
getShadowRoot() configuration option, enabling support for closed shadows1d5fcb5: Fixed: Form elements in disabled fieldsets should not be tabbable/focusable
bf0a8f0: Exposed an option to select the way that an element is checked as displayed
f9f6d25: Replaces Karma/Mocha/Sinon/Chai in test suite with Jest/Dom Testing Library. Removes README reference to identifying anchor tags with an xlin
xlink:href attribute as tabbable since that information is incorrect.c048203: fix crash when radio button name attributes contain CSS selector special characters
a188c71: use element.matches fallback for IE11 and Webkit5
./dist directory for various targets.5579825: fixes to details elements
d3c6514: Fix UMD build incorrectly using focusTrap as output name.
focusTrap as output name.fb49d23: Fix #96: Transpile non-minified bundles for expected browser targets.
bd21d91: Add focusable() for getting all focusable nodes.
focusable() for getting all focusable nodes.tabbable has been fixed: Was Array<Element> (an Element is technically not focusable), is now Array<HTMLElement | SVGElement> (which are both still/also Element instances).position: fixed) containers should now be consistently found in supported browsers.prepublishOnly script with prepare script. This has the added benefit of running automatically when installing the package from GitHub (as supported by NPM) where the published ./dist directory is not automatically included.focusable() type definition.#__PURE__ annotation has been added to allow dropping one of the top-level calls (if its result stays unused) and removed minification of the file referenced as package.json#module to avoid dropping the comments (including existing #__PURE__ annotations).Changed code formatting to use dangling commas where ES5 supports them.
<audio controls /> and <video controls /> elements without tabindex attribute specified would be deemed NOT tabbable in Chrome, but would be in FireFox, because Chrome has tabIndex (the DOM Element property) returning -1 (focusable, but not tabbable), while FireFox has tabIndex returning 0 (focusable, and tabbable), yet both browsers include these elements in the regular tab order (as if tabIndex was 0 for both browsers). Now these elements are considered tabbable in Chrome too!<summary> element directly under a <details> element as tabbable and focusable.isTabbableRadio() internal function in order to better support nested radio buttons:
tabbable().tabbable -> `import { tabbable } from 'tabbable';tabbable.isTabbable -> `import { isTabbable } from 'tabbable';tabbable.isFocusable -> `import { isFocusable } from 'tabbable';package.json now states sideEffects: false to mark this module as having no side effects as a result of merely importing it../dist/index.umd.*.Improve performance by changing the method for detecting whether a DOM node is focusable or not. It's expected that this change will _not_ affect resu
Fix reference to root element that caused errors within Shadow DOM.
Allow module to be imported by non-browser JavaScript.
Add tabbable.isFocusable and tabbable.isTabbable functions.
tabbable.isFocusable and tabbable.isTabbable functions.Add [contenteditable] elements.
[contenteditable] elements.Add and elements with controls attributes.
<audio> and <video> elements with controls attributes.checked on in their group, or if none in their group are checked.Fix bug causing SVG elements to precede elements they should follow in the tab order in IE.
Ensure querySelectorAll receives a string argument.
querySelectorAll receives a string argument.Fix crash when you call tabbable(document) (passing the document element).
tabbable(document) (passing the document element).- Add includeContainer option.
includeContainer option.Allows operation against elements that reside within iframes, by inspecting the element to determine its correct parent document (rather than relying
document (rather than relying on the global document object).Ensure stable sort of tabindexed elements even in browsers that have an unstable Array.prototype.sort.
tabindexed elements even in browsers that have an unstable Array.prototype.sort.Check tabindex attribute (via getAttribute), in addition to node.tabIndex, to fix handling of SVGs with tabindex="-1" in IE.
tabindex attribute (via getAttribute), in addition to node.tabIndex, to fix handling of SVGs with tabindex="-1" in IE.Children of visibility: hidden elements that themselves have visibility: visible are considered tabbable.
visibility: hidden elements that themselves have visibility: visible are considered tabbable.- Fix IE9 compatibility.
Further improvements to caching.
Fix overaggressive caching that would prevent tabbable from knowing an element's children had changed.
tabbable from knowing an element's children had changed.Fix handling of elements with tabindex="0".
<a> elements with tabindex="0".- Initial release.
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →