NIPE / Caret Geometry

Integrations / Vanilla

Geometry without a positioner.

Read the caret rectangle directly when simple viewport placement is enough.

const update = () => {
  const rect = getCaretRect(textarea)
  popup.hidden = !rect
  if (!rect) return
  popup.style.left = `${rect.left}px`
  popup.style.top = `${rect.bottom + 6}px`
}

const observer = observeCaretGeometry(textarea, update)
update()

// cleanup
observer.disconnect()
This is fine for a small indicator. It does not add collision handling, flipping, or environmental tracking. Add a positioning engine when those matter.

Input controls and editable DOM

For inputs and textareas, Caret Geometry performs text-control measurement. For contenteditable, Range and Selection, it uses browser-native geometry wherever possible. The same rectangle contract reaches your positioning code.

Use the element instead when appropriate

If the popup belongs next to the input box rather than the caret inside it, pass the input element directly to your positioner. Caret Geometry is unnecessary in that case.