Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

216
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda