Search code examples
javascripthtmlcssrangegetboundingclientrect

Why Range.getBoundingClientRect() returns 0 for range inside textarea?


I have <textarea> element and create range inside it:

  • Create new range via document.createRange()
  • Get the only child node of <textarea> via textarea.childNodes[0]
  • Set range start and range end via range.setStart and range.setEnd

Then I call range.getBoundingClientRect():

let textarea = document.querySelector('textarea');
let node = textarea.childNodes[0];

let range = document.createRange();
range.setStart(node, 3);
range.setEnd(node, 5);
console.log(range.getBoundingClientRect());
<textarea>aa bb cc</textarea>

But I receive ClientRect object with all zero fields, that is left = top = width = height = 0. Why these fields are zeros?


Note that all works fine if I replace <textarea> with usual div:

let textarea = document.querySelector('div');
let node = textarea.childNodes[0];

let range = document.createRange();
range.setStart(node, 3);
range.setEnd(node, 5);
console.log(range.getBoundingClientRect());
<div>aa bb cc</div>


Solution

  • <textarea> is a replacement element

    Objects inserted using the CSS content property are anonymous replaced elements. They are "anonymous" because they don't exist in the HTML markup.