pawelmysior
pawelmysior

Reputation: 3250

Rotate div 90 degrees and position fixed in the upper left corner

This is what I'm trying to accomplish:

preview

I want to have a navigation that will be rotated 90 deegres and fixed to the upper left corner of the window.

HTML:

<div class="outer">
    <div class="inner">
        <ul class="list">
            <li class="item">lasange</li>
            <li class="item">spaghetti</li>
        </ul>
    </div>
</div>

CSS:

.outer {
    position: fixed;
    left: 20px;
    top: 20px;
    background: red;
}

.inner {
    -webkit-transform: rotate(-90deg);
    transform-origin: 0 0;
    background: green;
}

I can't get it to look like in the image above. The problem is with the rotation. The inner div is positioned and then rotated, and as a result ends up outside the outer div. No matter what I put as the origin of the transformation it doesn't work the way I want it to. I've tried positioning the inner div with position: absolute but with no luck. I don't know the height/width parameters of the menu list.

Here's a fiddle: https://jsfiddle.net/949cjcnq/7/

Any help would be greatly appreciated.

Best regards, Paul

Upvotes: 10

Views: 15686

Answers (5)

vals
vals

Reputation: 64164

You can add a translateX(-100%) to your transform, that will set it where you want

.outer {
    position: fixed;
    left: 20px;
    top: 20px;
    background: red;
}

.inner {
    -webkit-transform: rotate(-90deg) translateX(-100%);
    transform: rotate(-90deg) translateX(-100%);
    transform-origin: 0 0;
    background: green;
}

.list {
  margin-top: 0px;
}
<div class="outer">
    <div class="inner">
        <ul class="list">
            <li class="item">lasange</li>
            <li class="item">spaghetti</li>
        </ul>
    </div>
</div>

Upvotes: 0

Rene van der Lende
Rene van der Lende

Reputation: 5281

In the below snippet you will see that I removed the outer and inner html and just rotated the entire UL -90deg. The result is your example image. Further proper styling is up to you ;-)

See snippet for comments:

/* {outline: 1px dotted red } /* for debugging */

ul, li { list-style-type: none; padding: 0; margin: 0 }

ul { height: 1; /* 1 x line-height */
    position: relative;
    float: left;
    padding: 0 6px;

    /* would be regular without transform */
    top: 20px; left: 20px;

    /* but transform-origin now pivots around
    top-right so UL element gets moved right.
    So left position needs correction:
    left = -1 x (total width of LI's + line-height + UL margin-LR + UL padding-LR) + wanted-left-margin */
    top: 20px; left: -134px; /* (optically estimated) */  
}

li {
    display: inline; /* result is horizontal menu */
}

.list {
    transform: rotate(-90deg); /* removed -webkit-*/
    transform-origin: top right;
    background: #acc9d7;
}
<ul class="list">
    <li class="item">lasange | </li>
    <li class="item">spaghetti</li>
</ul>

Upvotes: 0

MMachinegun
MMachinegun

Reputation: 3074

So I manage to position it the way you want, no matter how big your content is using position: absolute; for your .inner-div.

The only drawback is that your text is facing downwards and not upwards. Couldn't get around that issue with my CSS :S

If you -webkit-transform: rotate(180deg); the child of .inner you can turn the text the right way up :)

.outer {
  position: fixed;
  left: 20px;
  top: 20px;
  background: red;
}

.inner {
  position: absolute;
  bottom: 100%;
  -webkit-transform: rotateZ(90deg);
  transform-origin: 0 100%;
  background: #AACAD7;
  white-space: nowrap;;
}
.rotate {
  -webkit-transform: rotate(180deg);
}
ul { list-style: none; padding: 0; margin: 0; white-space: nowrap; }
ul li { padding: 5px 10px; }
<div class="outer">
  <div class="inner">
    <ul class="list rotate">
      <li class="item">lasange | spaghetti</li>
    </ul>
  </div>
</div>

Upvotes: 8

Spencer Wieczorek
Spencer Wieczorek

Reputation: 21565

Despite what you chose for the angle or rotation unfortunately you cannot do this without knowing the width of your item, as such I don't think it can be done in pure CSS/CSS3 without an expanded framework. As such to solve this you will need to use some JavaScript and get the computed width of the element and change the transformation appropriately:

var inner = document.querySelectorAll('.inner')[0];
var width = inner.offsetWidth;
inner.style.transform = "translateY("+width+"px) rotate(-90deg)";

Keep transform-origin: 0 0 as it will have the top of the element to the edge of the screen. Then we simply need to translate in the Y direction by the width, this will place the element in the left corner:

Fiddle Example

Upvotes: 1

Zach P
Zach P

Reputation: 570

I think what you want to do is move the rotation from the inner to the outer class. Your css should look like this:

.outer {
    -webkit-transform: rotate(-90deg);
    position: fixed;
    left: 20px;
    top: 80px;
    background: red;
}

.inner {
    background: green;
}

To make the text appear side by side after rotation, using a table would work better than using a list:

<div class="outer">
    <div class="inner">
        <table class="list">
            <tr>
                <td class="item">lasange</td>
                <td class="item"> | </td>
                <td class="item">spaghetti</td>
            <tr>
        </table>
    </div>
</div>

Working Fiddle: https://jsfiddle.net/949cjcnq/12/

Upvotes: 1

Related Questions