Skip to content

Browser support

penciled draws highlights with the CSS Custom Highlight API, and its default styles use CSS light-dark(). Both are supported in every current major browser:

Browser Highlight API With the default styles
Chrome, Edge (desktop and Android) 105+ 123+
Safari (macOS and iOS) 17.2+ 17.5+
Firefox (desktop and Android) 140+ 140+

The Highlight API column is the minimum for the engine to work, for example with penciled/headless and your own styles. The default styles column is the minimum for penciled/styles.css to look right: in older versions light-dark() isn’t understood, so highlight colors and the toolbar’s colors don’t apply.

Desktop and mobile are both supported. On touch devices the toolbar opens below the selection, so it doesn’t collide with the operating system’s own selection menu, and its buttons are larger.

There is no fallback that wraps text in elements, because that would mean changing your DOM. In a browser without the Highlight API, annotate() logs a warning and returns an instance that does nothing: the page works as before, without annotations. Its methods are safe to call, getAll() returns an empty array and ready resolves immediately.

To detect support yourself, for example to hide a hint about highlighting:

const supported = typeof CSS !== 'undefined' && 'highlights' in CSS;

Importing penciled, penciled/headless or penciled/react doesn’t touch window or document, so it’s safe in Node, Deno, Bun and edge runtimes. Only annotate() needs a browser.