Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

222
Views
getBoundingClientRect() + "transform: rotate()" is bugged in Chrome?

In certain cases getBoundingClientRect() produces wrong results and is hence an unreliable function. In Chrome at least. Example:

var greenRectangle = document.getElementById("target")
var rect = greenRectangle.getBoundingClientRect()
var visualized = document.createElement("div")
visualized.style.position = "absolute"
visualized.style.border = "1px solid red"
visualized.style.top = rect.top+"px"
visualized.style.left = rect.left+"px"
visualized.style.width = rect.width+"px"
visualized.style.height = rect.height+"px"
visualized.style.background = "#ff00002e"
document.body.appendChild(visualized)
<html>
    <body>
        <div style="transform: translate(10px, 42px);">
            <div style="width: 100px;height: 300px;background: black;">
                    <div style="transform: translate(140px, -10px);width: 400px;height: 300px;">
                        <div>
                            <div id="target" style="transform: translate(89px, 28px) rotate(2rad); width: 200px; height: 100px; background: green;"></div>
                        </div>
                    </div>
            </div>
        </div>
    </body>
</html>

If the green rectangle is rotated then getBoundingClientRect() on it returns a wrong bounding rectangle - here shown in red. I have tested this in Firefox and there are no problems there. It seems to have something to do with the empty div wrapper around the green rectangle. Without it getBoundingClientRect() works correctly. It looks like a Chrome bug to me. Is there a way to work around that?

EDIT: This seems to have been fixed by now, at least for the example case in this snippet. I'm not sure if there are other cases where getBoundingClientRect() returns wrong values.

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

SVG LINE BOUNDING CALCULATION ERROR - STILL CHROME

UPDATE: More information on this bug can be found here: SVG getBoundingClientRect() + "transform: rotate()" is bugged in Chrome in a very specific way

I've spent some time trying to hunt down why I wasn't getting the correct ClientBounds which led me to this question. You stated "I'm not sure if there are other cases where getBoundingClientRect() returns wrong values.". Well, it turns out there are more cases. This time in regard to SVGs but it is quite peculiar. I thought I'd leave this here for anyone else that comes across your post with a similar problem.

getBoundingClientRect() works fine on all SVG elements except in the circumstance when an element is rotated.

Below I have drawn 2 lines, the one on the left is diagonal, the right line starts vertical as represented by the black line. The green box is a visual representation of the getBoundingClientRect(). I then apply the same transform rotate to both lines at the same time and then update the bounding box visual.

As you can see from the following, the left bounding box doesn't represent the actual bounds, however, the right one does.

let l1 = document.getElementById("line1"),
  l2 = document.getElementById("line2"),
  vis1 = document.createElement("div"),  
  vis2 = document.createElement("div"),
  r = 0;

let setUpVis = (element) => {
  document.body.appendChild(element)
  element.style.position = "absolute"
  element.style.border = "1px solid green"
  element.style.background = `#0FF0002e`
}

let updateBounds = (element, displayElement) => {
  element.setAttribute("transform", `rotate(${r} 80 80)`); 
  let rect = element.getBoundingClientRect()
  displayElement.style.top = rect.y+"px"
  displayElement.style.left = rect.x+"px"
  displayElement.style.width = rect.width+"px"
  displayElement.style.height = rect.height+"px"
}

setUpVis(vis1)
setUpVis(vis2)

setInterval(() => { 
    updateBounds(l1, vis1);
  updateBounds(l2, vis2);
  r++; 
  if(r===360) r=0;
}, 10)
.container {
  width:170px;
  height:170px;
  display:inline-block;
}
<svg xmlns="http://www.w3.org/2000/svg" class="container">
  <line x1="40" y1="40" x2="120" y2="120" stroke="black" stroke-width="2"></line>
  <line x1="40" y1="40" x2="120" y2="120" id="line1" stroke="red" stroke-width="2"></line>
</svg>

<svg xmlns="http://www.w3.org/2000/svg" class="container">
  <line x1="80" y1="30" x2="80" y2="130" stroke="black" stroke-width="2"></line>
  <line x1="80" y1="30" x2="80" y2="130" id="line2" stroke="red" stroke-width="2"></line>
</svg>

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!