18
votes

Consider the following attempt to rotate a paragraph 90 degrees and position it so that the corner that was initially its top-left corner (and which therefore becomes its top-right corner after the rotation) ends up located at the top-right corner of the parent block.

HTML:

<!DOCTYPE html>
<html>
<body>
  <div id="outer">
    <p id="text">Foo bar</p>
  </div>
</body>
</html>

CSS:

#outer {
    border: solid 1px red;
    width:600px;
    height: 600px;
    position: relative;
}

#text {
        transform: rotate(90deg); 
        position: absolute;
        top: 0;
        right: 0;
}

In Firefox 19.0.2 on OS X 10.6.8, it fails. This appears to be because, despite the order in which the CSS properties were given, the transformation is applied after the positioning. In other words, the browser:

  1. places #text such that its top-right corner is located at the top-right corner of the parent block, but only then
  2. rotates it, with the result that what is now its top-right corner is not located at the top-right corner of the parent block.

As a result, the transform-origin property isn't much use here. If, for instance, one used transform-origin: top right; then #text would need to be moved downwards by the width it had before it was rotated.

My question: is there a way to tell the browser to apply the CSS positioning properties after the rotation; and if not, then is there instead a way to move #text downwards (e.g. using top:) by the width it had before it was rotated?

NB. Ideally the solution should not require setting a fixed width: for #text, and must not require JavaScript.

6
Do you mean you want your text object to fit to the right-top corner of it's wrapper after rotation, right? - Farid Rn
@faridv, I want to rotate a <p> element 90 degrees clockwise and position it so that the corner that is its top-left corner before the rotation (and which therefore becomes its top-right corner after the rotation) ends up at exactly the same location as the top-right corner of the <p> element's parent block. - user82216
The order in which you write the two properties doesn't matter. Positioning is always applied before any transforms. - Ana
you mention the browsers it fails on; which browsers have you tested where it succeeds? - Spudley

6 Answers

9
votes

You can apply more than one transform to an element, and the order does matter. This is the simplest solution: http://jsfiddle.net/aNscn/41/

#outer {
    border: solid 1px red;
    width:600px;
    height: 600px;
    position: relative;
}

#text {
    background: lightBlue;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;

    transform: translate(100%) rotate(90deg);
    transform-origin: left top;

    -webkit-transform: translate(100%) rotate(90deg);
    -webkit-transform-origin: left top;
}

The transform origin is the point around which a transformation is applied. For example, the transform origin of the rotate() function is the center of rotation - https://developer.mozilla.org/en-US/docs/Web/CSS/transform-origin

3
votes

Rotating -90deg.

 .rotate {
        position:absolute;
       -webkit-transform-origin: left top;   
        /* Safari */
        -webkit-transform: rotate(-90deg) translateX(-100%);

        /* Firefox */
        -moz-transform: rotate(-90deg) translateX(-100%);

        /* IE */
        -ms-transform: rotate(-90deg) translateX(-100%);

        /* Opera */
        -o-transform: rotate(-90deg) translateX(-100%);
   }
1
votes

Solved: here

This is the code I've added:

left: 100%;
width: 100%;
-webkit-transform-origin: left top;

I've also added some prefixed transform properties so it will be cross browser

-webkit-transform:rotate(90deg);
-moz-transform:rotate(90deg);
-ms-transform:rotate(90deg);
-o-transform:rotate(90deg);
transform:rotate(90deg);

How I did it:

I've found this question and, as the name of the website says, "fiddled" with the code to obtain this behavior. I guess the solution is left: 100%; instead of right: 0;.

(the width: 100%; is there because for some reason it wasn't 100% and the text would overflow to the next line)

1
votes

You may want to try using CSS3 @keyframes animation. It will allow you to rotate and reposition in any order you like. Here is a tutorial that may help: [CSS-Tricks][1]

.container {
  position: relative;
  width: 200px;
  height: 200px;
  border: 1px solid red;
}
p {
  border: 1px solid blue;
  position: absolute;
  top: auto;
  right: 0;
  display: inline-block;
  margin: 0;
  animation: 1s rotate 1s both;
}
@keyframes rotate {
  0% {
    transform-origin: top left;
    transform: rotate(0deg);
    right:0;
  }
  50% {
    right:0;
  }
  100% {
    transform-origin: top left;
    transform: rotate(90deg);
    right: -64px;
  }
}
<div class="container">
  <p>some text</p>
</div>
0
votes

You might want to play around with the translate option which you can apply as the second transform function after rotate and place your element at the exact position that you want to. There is no other way I guess to tell the browser to use the position properties after the transform function is used using plain css.

See this demo - http://codepen.io/anon/pen/klImq

-1
votes

Place "!important" at the end of the transform line.