<h1>Demo for incorrect <code>Range.getBoundingClientRect()</code> behavior:</h1>
<input></input>
<div id="testarea" contenteditable>
<p>Here's some text.</p>
<table>
<tr><td>a</td><td>b</td></tr>
<tr><td>c</td><td></td></tr>
</table>
<p>Set caret to this text and then repeatedly extend selection with key combination <kbd>Shift</kbd> + <kbd>Left Arrow</kbd> repeatedly until selection start is in the cell marked with letter "c". Note that that bug appears both with extended selection range and with collapsed selection range (that is, while moving the cursor with arrow keys only).</p>
<p>
Note that the bounding box is all zeroes when caret is actually on the right side of the table (caret is rendered as full table height), or when the caret is in the forth (empty) table cell, or caret is on the left side of the table. The bounding box should cover the area used for the blinking caret. Note the #visualfocus element skipping to top left corner instead!</p>
<p>There seems to be similar problem with <b>right edge</b> of images such as <img alt="[image here]"> (only alt text intentionally shown). However, the image also shows the same problem on the left edge if the element is first component on a single line!</p>
</div><!-- end of #testarea -->
<div id="visualfocus"></div>
<code id="textboundingbox"></code>
let visualfocus = document.getElementById("visualfocus");
let testarea = document.getElementById("testarea");
let textboundingbox = document.getElementById("textboundingbox");
testarea.addEventListener("keydown", function()
{
// do following after flushing event queue once
setTimeout(function()
{
let selection = window.getSelection();
// create collapsed range at the caret (regardless of selection length):
let range = new Range();
range.setStart(selection.focusNode, selection.focusOffset);
range.setEnd(selection.focusNode, selection.focusOffset);
let boundingbox = range.getBoundingClientRect();
// Note that this demo simply puts bounding box values to target element, this doesn't work if content is scrolled downwards
visualfocus.style.top = boundingbox.top + "px";
visualfocus.style.left = boundingbox.left + "px";
visualfocus.style.width = boundingbox.width + "px";
visualfocus.style.height = boundingbox.height + "px";
textboundingbox.innerText = JSON.stringify(boundingbox, null, 2);
}, 0);
});
Please Whitelist JSFiddle in your content blocker.
Help keep JSFiddle free for always by one of two ways:
Whitelist JSFiddle in your content blocker (two clicks)
Go PRO and get access to additional PRO features →
Join the 4+ million users, and keep the JSFiddle dream alive.
Ad-free
All ads in the editor and listing pages are turned completely off.
Use pre-released features
You get to try and use features (like the Palette Color Generator) months before everyone else.
Fiddle collections
Sort and categorize your Fiddles into multiple collections.
Private collections and fiddles
You can make as many Private Fiddles, and Private Collections as you wish!
Console
Debug your Fiddle with a minimal built-in JavaScript console.