v149 · Web APIs · DOM

OpaqueRange

Chrome 149 adds element.createValueRange(start, end) to <input> and <textarea> elements — a live range object that exposes geometry (bounding rects) for a span of the control's value text, without leaking the internal DOM.

concepts

  1. Geometry Inspector

    Select text inside a <textarea> and watch createValueRange().getBoundingClientRect() report the pixel position in real time — visualised as an overlay rectangle that follows your selection.

  2. Word Tooltip

    Click any word in a text field to see a positioned tooltip anchored precisely over that word using OpaqueRange geometry — the kind of inline suggestion or annotation UI that previously required fragile hacks.

  3. Inline Annotation

    Select any text span in the editor, add a note, and hover the annotation list to see the tooltip appear exactly over that phrase — all positioned using createValueRange().getBoundingClientRect(). Demonstrates a real-world annotation workflow.

  4. Selection Bounds

    Live canvas overlay that tracks your text selection in real time using createValueRange(selectionStart, selectionEnd). Toggle between the single bounding rect and the per-line client rects to see exactly how multi-line selections decompose into individual rectangles.

  5. Spellcheck Overlay

    Custom spellcheck that draws wavy, straight, or dotted underlines directly beneath misspelled words using getClientRects() geometry. Shows how to build inline error indicators without touching the DOM inside the form control.

  6. Range Geometry Explorer

    Interactive explorer of all OpaqueRange geometry APIs. Select a region, then compare getBoundingClientRect() vs getClientRects() outputs as animated overlays. Includes a multi-line selection decomposition view and a live coordinate readout showing how cross-line selections split into per-line rectangles.

why it shipped

Before Chrome 149, there was no way to obtain the pixel coordinates of a span of text inside a form control. You could call getBoundingClientRect() on the element itself, but not on a substring of its value. This blocked rich editor UIs from positioning inline popovers, suggestions, spell-check tooltips, and annotation anchors precisely over the typed text. OpaqueRange closes that gap: createValueRange(start, end) returns a live object that exposes getBoundingClientRect() and getClientRects() for any character slice. It is deliberately "opaque" — startContainer and endContainer are always null to preserve the encapsulation of the internal shadow DOM — so the geometry is available without breaking form-control security boundaries.

references