Mark Greenwood Team : Web Development Tags : Web Development Tips & Tricks

Rotating HTML elements (by an arbitrary amount) cross browser

Mark Greenwood Team : Web Development Tags : Web Development Tips & Tricks

There are lots of articles about rotating objects, but for some reason none of them seem to have all the pitfalls. I thought I'd try and write everything I've found down.

Here are the key points:

  • IE7/8 won't understand the CSS3's transform, so you'll have to generate an image transform matrix here.
  • IE7/8's point of origin for the rotation is at the top left rather than the center so you'll be doing some maths to calculate the new top left position.
  • IE7/8 changes the width / height of the rotated element. You'll have to store the actual width / height somewhere to use it to shift the element's point of origin.
  • IE8 rotates the element, but not always the elements contained within it. You'll have to rotate those as well!
  • When using jQuery, the position() method returns the top left of the new bounding box area where as the css() method will return the actual top/left position of the rotated element.

Here's the CSS / calculations for doing the actual rotation. (I've used javascript to do calculations)

Everything but IE7/8
degrees    // degrees to rotate

The CSS
transform: rotate(degrees)
-ms-transform: rotate(degrees)     /* IE 9 */
-moz-transform: rotate(degrees)    /* Firefox */
-webkit-transform: rotate(degrees) /* Safari and Chrome */
-o-transform: rotate(degrees)      /* Opera */


IE7/IE8
degrees    // degrees to rotate

var radians = degrees * (Math.PI * 2 / 360);
var costheta = Math.cos(radians);
var sintheta = Math.sin(radians);

The CSS (for the rotation)
sizingMethod:auto expand;
progid:DXImageTransform.Microsoft.Matrix("M11=cost
heta,M12=-sintheta,M21=sintheta,M22=costheta);


ew    // element width
eh    // element height

var x1 = -ew / 2,
    x2 =  ew / 2,
    x3 =  ew / 2,
    x4 = -ew / 2,
    y1 =  eh / 2,
    y2 =  eh / 2,
    y3 = -eh / 2,
    y4 = -eh / 2;

var x11 =  x1 * costheta + y1 * sintheta,
    y11 = -x1 * sintheta + y1 * costheta,
    x21 =  x2 * costheta + y2 * sintheta,
    y21 = -x2 sintheta + y2 * costheta,
    x31 =  x3 * costheta + y3 * sintheta,
    y31 = -x3 * sintheta + y3 * costheta,
    x41 =  x4 * costheta + y4 * sintheta,
    y41 = -x4 * sintheta + y4 * costheta;

var x_min = Math.min(x11, x21, x31, x41) + ew / 2,
    x_max = Math.max(x11, x21, x31, x41) + ew / 2;

var y_min = Math.min(y11, y21, y31, y41) + eh / 2;
    y_max = Math.max(y11, y21, y31, y41) + eh / 2;

The CSS (for shifting the point of origin)
left: x_min;
top: y_min;