Range and Selection

Selecting Text (Range and Selection)

A Range spans two boundary points, each a node plus an offset (a character index in a Text node). The document's Selection wraps a range but adds direction: the anchor is where the user started, the focus where they stopped, while a range's start always precedes its end.

The demo highlights every "DOM" with the CSS Custom Highlight API (Baseline 2025), which styles ranges via ::highlight() without inserting elements, then selects "API that" backward.

Highlighting ranges and inspecting a backward selectionHTMLLive
<style>p { font: 18px Georgia, serif; } ::highlight(hit) { background: #ffe082; }</style>
<p id="quote">The DOM is not JavaScript: the DOM is an API that JavaScript uses.</p>
<pre id="out" style="font-size: 14px"></pre>
<script>
  const text = document.querySelector('#quote').firstChild;          // the Text node
  const ranges = [...text.data.matchAll(/DOM/g)].map((m) => {
    const range = new Range();
    range.setStart(text, m.index); range.setEnd(text, m.index + 3);
    return range;
  });
  CSS.highlights.set('hit', new Highlight(...ranges));             // DOM unchanged
  const sel = getSelection();
  sel.setBaseAndExtent(text, 49, text, 41);                         // anchor after focus
  const r = sel.getRangeAt(0);
  document.querySelector('#out').textContent = `"${sel}" ${sel.direction}: anchor ` +
    `${sel.anchorOffset}, focus ${sel.focusOffset}; range ${r.startOffset}-${r.endOffset}`;
</script>
Browser output of Listing 8.20
Browser output of 20

Ranges also edit content (extractContents(), insertNode(), surroundContents()); listen for selectionchange on document to track the user.