focus-options-polyfill

Polyfill for the focusOptions preventScroll flag on HTMLElement.focus().

Library
npm
v1.6.0
47stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
28/100Needs Attention
Development Activity0
Maintenance20
Community20
Maturity60
Momentum12

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
72/100Good
Architecture68
Code Quality66
Innovation60
Learning Curve92

focus-options-polyfill is a tiny, dependency-free JavaScript polyfill that adds support for the WHATWG focusOptions argument to HTMLElement.focus(), specifically the preventScroll boolean. That option lets you programmatically focus an element without the browser automatically scrolling it into view, which is essential for accessible custom widgets, menus, and single-page-app navigation.

Older browsers ignore the option and always scroll on focus. This polyfill detects whether the native preventScroll option is honored and, when it is not, patches focus() to save and restore scroll positions around the focus call, reproducing the specified behavior transparently.

What You Get

  • Support for HTMLElement.focus({ preventScroll: true }) in non-compliant browsers
  • Automatic feature detection that no-ops when native support exists
  • Scroll-position save and restore across ancestor scrollable elements
  • A fallback for document.scrollingElement on older engines
  • A zero-dependency script that self-installs on import

Common Use Cases

  • Focusing an element in a custom widget without scrolling the page
  • Managing focus in single-page-app route changes without visual jumps
  • Building accessible menus and dialogs that move focus silently
  • Supporting preventScroll behavior in legacy browsers

Under The Hood

Architecture - The entire polyfill is a single IIFE in index.js. It guards against non-browser environments, then probes support by calling focus() with an object whose preventScroll getter records whether it was read (with a special-case workaround for a false positive in Edge 17-18). When support is absent, it stashes the native method as HTMLElement.prototype.nativeFocus and replaces focus: the replacement walks up the DOM collecting scrollable ancestors and the root scrolling element, records their scroll offsets, calls native focus, and restores those offsets so nothing visibly scrolls.

Tech Stack - Plain ES5-compatible JavaScript with no dependencies and no build step; the published main is the source index.js itself. An index.html demo page and lite-server dev script are included for manual testing.

Code Quality - The implementation is small and defensively written, handling missing globals, the Edge false positive, and a document.scrollingElement fallback. There is no automated test suite (the test script is a placeholder), which is the main quality caveat, though the surface area is minimal.

API Design - There is effectively no API to learn: importing the module installs the polyfill, after which the standard element.focus({ preventScroll: true }) call behaves per spec. This transparent, standards-aligned approach means no code changes beyond the import, keeping the learning curve essentially zero.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search