How do I position the caret inside a span element that has no text inside of it yet?

There's a nice trick with zero-width space that you may consider (look at at the code below) and CSS property white-space: pre that allows spaces to be "visible" when focused.

function makeTextNode() {
    return document.createTextNode('​') // <-- there a zero-width space between quotes

function placeCaretInSpan() {
  const range = document.createRange()
  const editable = document.getElementById("editable")
  const span = editable.querySelector("span")
  if (span.childNodes.length === 0) {
    span.appendChild(makeTextNode()) // <-- you have to have something in span in order to place caret inside
  range.setStart(span.childNodes[0], 1) // <-- offset by 1 to be inside SPAN element and not before it
  let selection = window.getSelection()
span {
    font-weight: bold;
    background: yellow;
#editable:focus {
    white-space: pre;
<div contenteditable="true" id="editable">This should be <span></span> editable.</div>
<button onclick="placeCaretInSpan()">place caret</button>