-
Notifications
You must be signed in to change notification settings - Fork 410
Description
Tip
Demo website: https://cderv.github.io/quarto-search-highlight-demo/
When navigating to a page via search (with ?q= parameter), the highlight() function adds <mark> elements around matching text. These marks are then cleared almost immediately (~24ms on quarto.org) by quarto-hrChanged events, making them invisible to users.
Steps to Reproduce
- Go to any Quarto website page with
?q=someterm(e.g.html-basics.html?q=format) - Observe that no highlighted text is visible
Instrumented testing on quarto.org shows marks appear and disappear within a single frame:
404ms: 17 <mark> elements added by highlight()
428ms: 0 <mark> elements — all cleared by resetHighlighting()
Root Cause
The clearing chain:
-
quarto-search.jsregisters a one-shot listener forquarto-hrChangedthat callsclearHighlight():
https://github.com/quarto-dev/quarto-cli/blob/aaaba63c2/src/resources/projects/website/search/quarto-search.js#L67-L76 -
quarto-nav.jsdispatchesquarto-hrChangedfromupdateDocumentOffset():
https://github.com/quarto-dev/quarto-cli/blob/aaaba63c2/src/resources/projects/website/navigation/quarto-nav.js#L196-L197 -
updateDocumentOffset()is triggered during initial layout settling by aResizeObserveron the header element and asetTimeout(250):
https://github.com/quarto-dev/quarto-cli/blob/aaaba63c2/src/resources/projects/website/navigation/quarto-nav.js#L254-L269
The comment says "Clear search highlighting when the user scrolls sufficiently", but the event fires from layout recalculation, not user interaction.
Context
PR #14003 added text fragments (:~:text=) to search result URLs, which provides browser-native scroll-to-text highlighting that persists independently. This effectively works around the broken <mark> behavior for visible text, but text fragments cannot highlight content inside hidden elements (e.g. inactive Bootstrap tab panes).
Possible Fix
Delay the quarto-hrChanged/quarto-sectionChanged listener registration to skip initial layout settling events, or gate the clearing on actual user interaction (scroll, click).