35

How do I retrieve the width and height properties after I've applied transform: rotate(45deg);?

Like, 11x11 square after rotation becomes 17x17 (Chrome result), but javascript still returns original width/height - 10x10.

How do I get this 17x17?

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
tomsseisums
  • 13,168
  • 19
  • 83
  • 145

4 Answers4

74

Instead of calculating it yourself, you can get this via the HTMLDOMElement's getBoundingClientRect().

This will return an object with the correct height and width, taking into account the transformation matrix.

jsFiddle.

alex
  • 479,566
  • 201
  • 878
  • 984
  • 3
    @Userpassword Yes, that's how jQuery works. You'd need to use `[0]` or `get(0)` or similar. – alex Feb 17 '15 at 22:28
  • 2
    I only got this to work correctly. Yes I know the question is old, but if the question was asked today I beilieve this should be the accepted answer. – bestprogrammerintheworld Feb 27 '15 at 08:17
  • 1
    This is so much simpler. Thank you. – ijb109 Jul 09 '15 at 16:59
  • 2
    Agreed with everyone else. This should be the accept answer versus the other over-engineered/complicated solutions. – Erutan409 Aug 14 '17 at 20:02
  • 1
    I know this type of comment isn't allowed but I like how @alex put OP's picture to jsfiddle instead of some random image xD – LuckyTuvshee Dec 03 '20 at 05:11
  • 1
    Be careful - getBoundingClientRect() values are affected by css transitions. If reported values are wrong, check if element has some css transitions applied and disable them. – userlond Dec 10 '20 at 02:44
  • @userlond. I also stumbled on this issue when applying a rotation. What worked for me is wrapping the call to getBoundingClientRect() into a window.requestAnimationFrame(). I.e. window.requestAnimationFrame( () => { clientRect = elem.getBoundingClientRect() }); – Marc Verkerk Dec 22 '22 at 08:50
21

Even if you rotate something the dimensions of it do not change, so you need a wrapper. Try wrapping your div with another div element and count the wrappers dimensions:

  <style type="text/css">
  #wrap {
    border:1px solid green;
    float:left;
    }

  #box {
    -moz-transform:rotate(120deg);
    border:1px solid red;
    width:11px;
    height:11px;
  }
  </style>

  <script type="text/javascript">
  $(document).ready(function() {
    alert($('#box').width());
    alert($('#wrap').width());
  });
  </script>
</head>

<body>
 <div id="wrap">
  <div id="box"></div>
  </div>
</body>

Redited: the wrapper solution is not working properly, as the wrapper is not automatically adjusted to the contents of the inner div. Follow the mathematical solution:

var rotationAngle;

var x = $('#box').width()*Math.cos(rotationAngle) + $('#box').height()*Math.sin(rotationAngle); 
alex
  • 479,566
  • 201
  • 878
  • 984
nonouco
  • 1,170
  • 1
  • 13
  • 25
  • Maybe in Firefox it doesn't change, but Chrome in inspector view shows calculated values. Wrapper is a great solution, but it's expensive. – tomsseisums Sep 27 '11 at 07:40
  • @Tom firefox behaves just like you described. first of all we need to keep clear that a rotated box has still the same dimensions. its like, if you rotate a piece of paper on your desk, its dimensions remain the same. thats why you need the wrapper. if you cant affort it you need mathematics to calculate the dimensions you need. the same mathematics, firefox uses internally to calculate wrap's dimensions. please consider my +1 here. – nonouco Sep 27 '11 at 07:47
  • Yeah, while you posted this, I already made a function to calculate new dimensions. -1 for CSS3/DOM3/HTML5 for not making native functions to retrieve these essential values. – tomsseisums Sep 27 '11 at 08:13
  • 4
    While hitting away on this, I finally figured out that cos/sin in javascript take radials! Not degrees! I hope I saved someone a little time with this comment ;) – Steven Van Ingelgem Feb 04 '13 at 20:20
  • The mathematical solution is working well for the width, how can I do the same to calculate the height? – Light Jun 09 '13 at 10:23
9

I made a function for this, domvertices.js

It computes the 4 vertices 3d coordinates of any, deep, transformed, positioned DOM element -- really just any element: see the DEMO.

a                b
 +--------------+
 |              |
 |      el      |
 |              |
 +--------------+
d                c

var v = domvertices(el);
console.log(v);
{
  a: {x: , y: , z: },
  b: {x: , y: , z: },
  c: {x: , y: , z: },
  d: {x: , y: , z: }
}

With those vertices, you can compute anything among: width, height... Eg, in your case:

// norm(a,b)
var width = Math.sqrt(Math.pow(v.b.x - v.a.x, 2) + Math.pow(v.b.y - v.a.y, 2));

See the README for more infos.

--

It is published as a npm module (with no dep), so just install it with:

npm install domvertices

Cheers.

abernier
  • 27,030
  • 20
  • 83
  • 114
  • 2
    Cool! A very nice add would be `width` and `height` (or `w,h`) for those of us who remember math not so good ;) Even as `function`s would be great if you want to avoid the calcs if they are not used. – Campbeln Dec 10 '15 at 01:05
  • @abernier [maybe you are the one who can answer my question (bounty +100)??? Any help is very apreciated...](https://stackoverflow.com/questions/45578101/formular-to-calculate-width-height-relative-to-parent-of-container-with-transl) – Axel Aug 16 '17 at 09:42
4

In case you're looking for a function to programmatically calculate these values...

// return an object with full width/height (including borders), top/bottom coordinates
var getPositionData = function(el){
    return $.extend({ width : el.outerWidth(false), height : el.outerHeight(false) }, el.offset());
};

// get rotated dimensions   
var transformedDimensions = function(el, angle){
    var dimensions = getPositionData(el);
    return { width : dimensions.width + Math.ceil(dimensions.width * Math.cos(angle)), height : dimensions.height + Math.ceil(dimensions.height * Math.cos(angle)) };
}

Here's a little something I put up. Probably not the best thing ever, but does the job for me.

tomsseisums
  • 13,168
  • 19
  • 83
  • 145