-
Notifications
You must be signed in to change notification settings - Fork 23k
Editorial review: Add docs for the HighlightRegistry.highlightsFromPoint() method #40390
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
estelle
merged 8 commits into
mdn:main
from
chrisdavidmills:highlightregistry-highlightsfrompoint
Jul 23, 2025
Merged
Changes from 3 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
d2d14a5
Add docs for the HighlightRegistry.highlightsFromPoint() method
chrisdavidmills fc68b5a
Fixes for ffiori review comments
chrisdavidmills 228f652
final few bits of cleanup
chrisdavidmills 47f07c1
Merge branch 'main' of github.com:mdn/content into highlightregistry-…
chrisdavidmills b0ebafe
Update files/en-us/web/api/highlightregistry/highlightsfrompoint/inde…
chrisdavidmills 3867bbb
Update files/en-us/web/api/highlightregistry/highlightsfrompoint/inde…
chrisdavidmills 620fa1d
Address estelle review comments
chrisdavidmills 6037da2
Split the JS section into two
chrisdavidmills File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
192 changes: 192 additions & 0 deletions
192
files/en-us/web/api/highlightregistry/highlightsfrompoint/index.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,192 @@ | ||||||||||
| --- | ||||||||||
| title: "HighlightRegistry: highlightsFromPoint() method" | ||||||||||
| short-title: highlightsFromPoint() | ||||||||||
| slug: Web/API/HighlightRegistry/highlightsFromPoint | ||||||||||
| page-type: web-api-instance-method | ||||||||||
| browser-compat: api.HighlightRegistry.highlightsFromPoint | ||||||||||
| --- | ||||||||||
|
|
||||||||||
| {{APIRef("CSS Custom Highlight API")}} | ||||||||||
|
|
||||||||||
| The **`highlightsFromPoint()`** method of the {{domxref("HighlightRegistry")}} interface returns an array of objects representing the custom highlights applied at a specific point within the viewport. | ||||||||||
|
|
||||||||||
| ## Syntax | ||||||||||
|
|
||||||||||
| ```js-nolint | ||||||||||
| highlightsFromPoint(x, y) | ||||||||||
| highlightsFromPoint(x, y, options) | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ### Parameters | ||||||||||
|
|
||||||||||
| - `x` | ||||||||||
| - : The x coordinate of the point within the viewport to return custom highlight information for. | ||||||||||
| - `y` | ||||||||||
| - : The y coordinate of the point within the viewport to return custom highlight information for. | ||||||||||
chrisdavidmills marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
| - `options` {{optional_inline}} | ||||||||||
| - : An object containing options, which can include: | ||||||||||
| - `shadowRoots` | ||||||||||
| - : An array of {{domxref("ShadowRoot")}} objects. Custom highlights that exist at the specified point inside shadow roots in the array will also be included in the return value, in addition to those present in the light DOM. By default, highlights inside shadow roots are not returned. | ||||||||||
|
|
||||||||||
| ### Return value | ||||||||||
|
|
||||||||||
| An array of `HighlightHitResult` objects representing the custom highlights applied at the specified point. Each object contains the following properties: | ||||||||||
chrisdavidmills marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
|
|
||||||||||
| - `highlight` | ||||||||||
| - : A {{domxref("Highlight")}} object representing the applied custom highlight. | ||||||||||
| - `ranges` | ||||||||||
| - : An array of {{domxref("AbstractRange")}} objects representing the ranges to which the custom highlight is applied. | ||||||||||
|
|
||||||||||
| If no custom highlights are applied at the specified point, an empty array is returned. This includes instances where the specified point is outside the viewport, that is, the coordinate values are negative or greater than the viewport dimensions. | ||||||||||
|
|
||||||||||
| ## Examples | ||||||||||
|
|
||||||||||
| ### Output custom highlights applied at the mouse pointer position | ||||||||||
|
|
||||||||||
| In this example, we provide a paragraph of text that you can apply custom highlights to. You can then double-click a point in the paragraph to output the text that has custom highlights applied at that point. | ||||||||||
chrisdavidmills marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
|
|
||||||||||
| #### HTML | ||||||||||
|
|
||||||||||
| The markup includes a {{htmlelement("p")}} element containing the text to apply custom highlights to, and a {{htmlelement("section")}} element that we will output the highlighted text fragments to. | ||||||||||
chrisdavidmills marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
|
|
||||||||||
| ```html live-sample___highlights-from-point-example | ||||||||||
| <h1>highlightsFromPoint() demo</h1> | ||||||||||
| <p class="highlight-text"> | ||||||||||
chrisdavidmills marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
| Deadlights jack lad schooner scallywag dance the hempen jig carouser broadside | ||||||||||
chrisdavidmills marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
| cable strike colors. Bring a spring upon her cable holystone blow the man down | ||||||||||
| spanker Shiver me timbers to go on account lookout wherry doubloon chase. | ||||||||||
| Belay yo-ho-ho keelhaul squiffy black spot yardarm spyglass sheet transom | ||||||||||
| heave to. | ||||||||||
| </p> | ||||||||||
| <h2>Highlighted text at point</h2> | ||||||||||
chrisdavidmills marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
| <section></section> | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| #### CSS | ||||||||||
|
|
||||||||||
| We have hidden most of the CSS for brevity; the most relevant CSS defines styling for three custom highlights named `highlight1`, `highlight2`, and `highlight3`. | ||||||||||
chrisdavidmills marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
|
|
||||||||||
| ```css hidden live-sample___highlights-from-point-example | ||||||||||
| * { | ||||||||||
| box-sizing: border-box; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| body { | ||||||||||
| background-color: #fff; | ||||||||||
| color: #333; | ||||||||||
| font: | ||||||||||
| 1em / 1.4 Helvetica Neue, | ||||||||||
| Helvetica, | ||||||||||
| Arial, | ||||||||||
| sans-serif; | ||||||||||
| padding: 1em; | ||||||||||
| max-width: 800px; | ||||||||||
| margin: 0 auto; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| section { | ||||||||||
| display: flex; | ||||||||||
| gap: 10px; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| .highlight-text, | ||||||||||
| article { | ||||||||||
| padding: 10px; | ||||||||||
| background-color: #eee; | ||||||||||
| border: 2px solid #ddd; | ||||||||||
| border-radius: 10px; | ||||||||||
chrisdavidmills marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
| } | ||||||||||
|
|
||||||||||
| .instructions { | ||||||||||
| font-size: 0.8rem; | ||||||||||
| } | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| ```css live-sample___highlights-from-point-example | ||||||||||
| :root::highlight(highlight1) { | ||||||||||
| background-color: rgb(255 255 0 / 0.5); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| :root::highlight(highlight2) { | ||||||||||
| background-color: rgb(255 0 0 / 0.5); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| :root::highlight(highlight3) { | ||||||||||
| background-color: rgb(0 0 255 / 0.75); | ||||||||||
| color: white; | ||||||||||
| } | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| #### JavaScript | ||||||||||
|
|
||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. updated |
||||||||||
| In our script, we start by grabbing references to the `<p>` element, its contained text node, and our `<section>` element. We then create an array called `customHighlights` that contains our custom highlight names, and a variable called `currentHighlight`, initially set to `0`, which will be used to specify which custom highlight to apply later on. | ||||||||||
chrisdavidmills marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
|
|
||||||||||
| ```js live-sample___highlights-from-point-example | ||||||||||
| const pElem = document.querySelector(".highlight-text"); | ||||||||||
chrisdavidmills marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
| const textNode = pElem.firstChild; | ||||||||||
| const section = document.querySelector("section"); | ||||||||||
chrisdavidmills marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
| const customHighlights = ["highlight1", "highlight2", "highlight3"]; | ||||||||||
chrisdavidmills marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
| let currentHighlight = 0; | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| Next, we define a keyboard control — <kbd>h</kbd> — that when pressed applies a custom highlight to any text selected inside the paragraph text. This consists of a [`keydown`](/en-US/docs/Web/API/Element/keydown_event) event handler function that only runs its contents if the pressed key was <kbd>h</kbd>. If so, we grab the selected text using {{domxref("Window.getSelection()")}} and convert it to a {{domxref("Range")}} using {{domxref("Selection.getRangeAt()")}}. | ||||||||||
chrisdavidmills marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
|
|
||||||||||
| Next, we check that the `range` object's [`startContainer`](/en-US/docs/Web/API/Range/startContainer) and [`endContainer`](/en-US/docs/Web/API/Range/endContainer) are both the paragraph text node, to make sure we don't allow any cross-container highlights. If so, we select the custom highlight we want to apply to the `range` using `customHighlights[currentHighlight]`, then increment `currentHighlight`; if it reaches `3`, we set it back to `0`. This has the effect of cycling through the available highlights in order as they are set. | ||||||||||
chrisdavidmills marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
|
|
||||||||||
| Finally for the `keydown` event handler, we create a new `highlight` object using the {{domxref("Highlight.Highlight", "Highlight()")}} constructor, passing it the `range` we created earlier. We then apply the chosen custom highlight style to `highlight` using the {{domxref("HighlightRegistry.set()")}} method. | ||||||||||
|
|
||||||||||
| ```js live-sample___highlights-from-point-example | ||||||||||
| window.addEventListener("keydown", (event) => { | ||||||||||
| if (event.key === "h") { | ||||||||||
| const selection = window.getSelection(); | ||||||||||
| const range = selection.getRangeAt(0); | ||||||||||
| if (range.startContainer === textNode && range.endContainer === textNode) { | ||||||||||
| const highlightStyle = customHighlights[currentHighlight]; | ||||||||||
| currentHighlight++; | ||||||||||
| if (currentHighlight === 3) { | ||||||||||
| currentHighlight = 0; | ||||||||||
| } | ||||||||||
chrisdavidmills marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
| const highlight = new Highlight(range); | ||||||||||
| CSS.highlights.set(highlightStyle, highlight); | ||||||||||
| } | ||||||||||
| } | ||||||||||
| }); | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| Next, we define a [`dblclick`](/en-US/docs/Web/API/Element/dblclick_event) event handler function to handle outputting the highlighted text at the mouse cursor position when the event fires. We first grab the current mouse coordinates from the event object ({{domxref("MouseEvent")}}). We then pass those coordinates into a `highlightsFromPoint()` call to return the custom highlights applied at that point. We then clear the contents of the `<section>` element, and loop through each highlight in the `highlights` array. | ||||||||||
|
|
||||||||||
| For each `highlight`, we grab the first range in the [`ranges`](#ranges) array (there is only ever one range in each highlight, in this case), then get the exact highlighted string using {{domxref("Range.toString()")}} and add it to the `<section>` element's `innerHTML`, inside an `<article>` element. | ||||||||||
|
|
||||||||||
| ```js live-sample___highlights-from-point-example | ||||||||||
| pElem.addEventListener("dblclick", (event) => { | ||||||||||
| const mouseX = event.clientX; | ||||||||||
| const mouseY = event.clientY; | ||||||||||
| const highlights = CSS.highlights.highlightsFromPoint(mouseX, mouseY); | ||||||||||
|
|
||||||||||
| section.innerHTML = ""; | ||||||||||
| for (highlight of highlights) { | ||||||||||
| const range = highlight.ranges[0]; | ||||||||||
| const textSelection = range.toString(); | ||||||||||
| section.innerHTML += `<article>${textSelection}</article>`; | ||||||||||
| } | ||||||||||
| }); | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| #### Result | ||||||||||
|
|
||||||||||
| Try selecting some sections of text, pressing <kbd>h</kbd> after each one to apply a highlight. Then try double-clicking on a highlighted section of text to see that section outputted at the bottom of the UI. If multiple highlights overlap the section, you'll see multiple text fragments outputted. | ||||||||||
chrisdavidmills marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
chrisdavidmills marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
|
|
||||||||||
| {{EmbedLiveSample("highlights-from-point-example", "100%", "600")}} | ||||||||||
|
|
||||||||||
| ## Specifications | ||||||||||
|
|
||||||||||
| {{Specifications}} | ||||||||||
chrisdavidmills marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
|
|
||||||||||
| ## Browser compatibility | ||||||||||
|
|
||||||||||
| {{Compat}} | ||||||||||
|
|
||||||||||
| ## See also | ||||||||||
|
|
||||||||||
| - {{domxref("css_custom_highlight_api", "The CSS Custom Highlight API", "", "nocode")}} | ||||||||||
chrisdavidmills marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
| - [CSS Custom Highlight API: The Future of Highlighting Text Ranges on the Web](https://css-tricks.com/css-custom-highlight-api-early-look/) | ||||||||||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.