The CSS Custom Highlight API allows browsers to style arbitrary text ranges without inserting any new DOM elements. advanced-mark.js supports this API natively: instead of wrapping matched text inDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/angezid/advanced-mark.js/llms.txt
Use this file to discover all available pages before exploring further.
<mark> elements, it registers StaticRange or Range objects with the browser’s highlight registry, leaving the DOM completely untouched. This is significantly faster for large documents because it eliminates DOM mutations and the reflow they trigger.
How it works
When aHighlight object is passed via the highlight option, advanced-mark.js:
- Creates
StaticRange(orRange) objects for every match it finds. - Adds those range objects to the provided
Highlightinstance. - Registers the
Highlightinstance withCSS.highlightsunder the name given byhighlightNameonce all matches have been processed.
<mark> elements are created. The visual highlight is rendered entirely by the browser using a CSS ::highlight() pseudo-element rule that you define in your stylesheet.
Basic usage
Check for browser support before constructing theHighlight object, then pass it to any mark(), markRegExp(), or markRanges() call:
::highlight() rule to your CSS:
highlight is undefined (i.e. the browser does not support the API), advanced-mark.js automatically falls back to wrapping matches in HTML elements, so your code works in all browsers without any additional branching.
When the Highlight API is active, the
each callback receives a StaticRange or Range object as its first parameter instead of an HTMLElement. Keep this in mind if you use the callback to attach classes, attributes, or data properties — those operations are not applicable to range objects.StaticRange vs Range
By default (staticRanges: true), advanced-mark.js creates StaticRange objects. Static ranges are lightweight snapshots that do not update when the DOM changes, making them significantly faster to create and store.
Range objects by setting staticRanges: false, but be aware of a serious performance caveat:
rangeAcrossElements
WhenacrossElements: true is set alongside the Highlight API, the rangeAcrossElements option (default true) controls whether a single range object is created for a match that spans multiple elements, or whether one range object is created per element:
rangeAcrossElements: false produces one StaticRange/Range per element touched by a match (equivalent to the number of <mark> elements that would have been created):
rangeAcrossElements: true, the filter callback’s first parameter is an array of text nodes rather than a single text node.
markRanges() does not require acrossElements to produce cross-element ranges — it handles element boundaries automatically regardless of this option.Highlight API with iframes and shadow DOM
To apply custom highlight styles inside iframes or shadow roots when using the Highlight API, add the::highlight() rule to the respective style option:
<style data-markjs> element into each iframe’s <head> and at the end of each shadow root’s child nodes, scoping the ::highlight() rule to those environments.
Removing highlights
Pass the sameHighlight object and highlightName to unmark() to clear the registered highlight:
Highlight entry from CSS.highlights and clears all range objects from it, effectively removing all visual highlights from the page.
Browser support
The CSS Custom Highlight API is supported in modern Chromium-based browsers and Safari 17.2+. Firefox support is under active development. advanced-mark.js handles missing support gracefully: iftypeof Highlight === 'undefined', the Highlight object you pass will be undefined, and the library will automatically fall back to wrapping matches in HTML elements using its standard DOM-based approach. No code changes are required to support both paths.