How can I improve usability for selection API on contenteditable
08:16 22 Jan 2026

I've got the following code which essentially checks the nodes and gets the line they belong to. I'm using the selection API. If the direction is not "none" then I'm getting the focus and anchor nodes and checking which line they belong to. Code below.

Selection Log

Text:
Line:
Selection:
Range:

function addIndentMetaToLines(lines, currentLineIndex, selection, editor = undefined) {
  if (selection.direction === "none") {
    lines[currentLineIndex].indentLevel += 1;
    return
  }
  // else check line / lines of selection
  console.log(selection);
  console.log([getCurrentLineIndex(editor, selection.anchorNode), getCurrentLineIndex(editor, selection.focusNode)].sort());
}

function getCurrentLineIndex(editor, node) {

  // keep helper encapsulated for now
  function findCurrentEditorChild(editor, node) {
    // if node parent is not div editor, set node to parent - repeat. when node parent is editor, then return node
    while (NOT(node.parentNode === editor)) {
      node = node.parentNode;
    }
    return node;
  }

  if (node === editor) {
    return 0;
  }
  const currentEditorChild = findCurrentEditorChild(editor, node)
  return Array.from(editor.childNodes).findIndex(node => node === currentEditorChild)

}

However the UI is not clear!

This is what I expect the UI to do. Expected UI

This is the behaviour that is unexpected. Unexepected UI

The selection direction is backwards and so the focusOffset is expected to be to the left of the anchorOffset. You can see that the selection looks identical. However in the first selection the UI correctly represents the selection belonging to a single line, whereas in the second selection. The UI shows only one line when the selection has spanned over two nodes.

Is this a CSS fix or a programming fix?

javascript selection