Joum
Joum

Reputation: 3245

Responsive fixed position side div

I'm trying to make (by myself, learning purposes) a sliding, fixed-position side menu div. I want to make it responsive to different viewport dimensions.

I'm having a problem, though: in the container div I have 2 other divs, the left (A) one has css-rotated text (in a span), the right (B) one has 3 checkbox inputs and text, each wrapped by a span. Something like:

container (w/ padding)
+----------------------+
| +---+   +----------+ |
| | A |   |     B    | |
| +---+   +----------+ |
+----------------------+

EDIT:

For instance, if the viewport grew, it should be something more like:

container (w/ padding)
+---------------------------+
| +---+   +---------------+ |
| |   |   |               | |
| |   |   |               | |
| |   |   |               | |
| | A |   |       B       | |
| |   |   |               | |
| |   |   |               | |
| |   |   |               | |
| |   |   |               | |
| +---+   +---------------+ |
+---------------------------+

Please note that the padding needn't change and that the width of the A div didn't change either (only its height). What changed was the total container width, height and the B div's width and height, as well as the checkboxes' fontsize.

/EDIT

What I want to accomplish is having the right side of the container out of view, scrolling into view when the left side div is clicked. The jQuery bit for the sliding purpose isn't troubling me right now, I just want to get the responsive bit (sizes, margins, font sizes) figured out before I get into sliding it.

Issue: the rotated text gets ill positioned and the padding isn't correctly displayed. What am I missing here?

This is what I have so far (snippet below):

.outer-wrapper{
	height: 100vh;
	width: 100vw;
    overflow: hidden;
    position: fixed;
	background: transparent;
}

.container{
  position: fixed;
  width: 25vw;
  height: 40vh;
  top: 30vh;
  right: 0;
  background: #222;
  color: #FFF;
  padding: 20px;
}

.left{
  width: 20%;
  	-webkit-transform: rotate(-90deg); 
	-moz-transform: rotate(-90deg); 
	-ms-transform: rotate(-90deg); 
	-o-transform: rotate(-90deg); 
	transform: rotate(-90deg);
}

.right{
  position: absolute;
  width: 80%;
  left: 20%;
}
<div class="outer-wrapper">
  <div class="container">
    <div class="left">
      <span>Menu</span>
    </div>
    <div class="right">
      <span><input type="checkbox" checked autocomplete="off"> Checkbox1</span><br>
      <span><input type="checkbox" checked autocomplete="off"> Checkbox2</span><br>
      <span><input type="checkbox" checked autocomplete="off"> Checkbox3</span>
    </div>
  </div>
</div>

Upvotes: 2

Views: 4859

Answers (3)

Cedric Reichenbach
Cedric Reichenbach

Reputation: 9319

I'm not sure where you want to position your "Menu" text, but the thing confusing you is probably the transform-origin, which is relevant (among others) for rotations and represents a fixed point around which rotation happens. Default is center, but you probably want to rotate around bottom right or something like that.

Instead of absolutely positioning left or right, I suggest you simply make them float: left, which will align them from left to right with no spaces inbetween (and since withs add up to 100%, no line wrap will happen).

Update

Apparently, you want to have "Menu" centered inside the left part. To do so, it's probably best to have an absolutely positioned element inside left, which is located 50% from top, has 100% width and centered text. Then, rotate it by 90 degrees around its center.

Please note that I also changed your container's padding into a border in order to prevent issues caused different measurements between absolutely and relatively positioned elements. If that's a problem, you could always switch to a solution with another container and give a padding to the outer one.

.outer-wrapper{
	height: 100vh;
	width: 100vw;
    overflow: hidden;
    position: fixed;
	background: transparent;
}

.container{
  position: fixed;
  width: 40vw;
  height: 40vh;
  top: 30vh;
  right: 0;
  background: #222;
  color: #FFF;
  padding: 0;
  border: 20px solid #222;
}

.left{
    float: left;
    width: 20%;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
}

.left .text {
    position: absolute;
    top: 50%;
    margin-top: -0.6em; /* ~ half a line-height */
    left: 0;
    right: 0;
    text-align: center;
    transform: rotate(-90deg);
    transform-origin: center;
}

.right{
  float: left;
  width: 80%;
  margin-left: 20%;
}
<div class="outer-wrapper">
  <div class="container">
    <div class="left">
      <div class="text">Menu</div>
    </div>
    <div class="right">
      <span><input type="checkbox" checked autocomplete="off"> Checkbox1</span><br>
      <span><input type="checkbox" checked autocomplete="off"> Checkbox2</span><br>
      <span><input type="checkbox" checked autocomplete="off"> Checkbox3</span>
    </div>
  </div>
</div>

Upvotes: 0

Paulie_D
Paulie_D

Reputation: 115011

I've added an inner-wrapper div but this could work without it with few adjustments.

The menu container is not rotated but the content span is but is positioned absolutely inside that menu.

The borders are merely for reference.

Codepen Demo

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
.outer-wrapper {
  height: 100vh;
  width: 100vw;
  overflow: hidden;
  position: fixed;
  background: transparent;
}
.container {
  position: fixed;
  width: 25vw;
  top: 10vh; /* changed for snippet demo only */
  right: 0;
  background: #222;
  color: #FFF;
}
.inner-wrapper {
  height: 80vh; /* increased for snippet demo only */
  padding: 20px;
}
.left {
  width: 20%;
  height: 100%;
  float: left;
  border: 1px solid red;
  text-align: center;
  position: relative;
}
.left span {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(-90deg);
}
.right {
  height: 100%;
  width: 80%;
  float: right;
  border: 1px solid green;
}
<div class="outer-wrapper">
  <div class="container">
    <div class="inner-wrapper">
      <div class="left">
        <span>Menu</span>
      </div>
      <div class="right">
        <span><input type="checkbox" checked autocomplete="off"> Checkbox1</span>
        <br>
        <span><input type="checkbox" checked autocomplete="off"> Checkbox2</span>
        <br>
        <span><input type="checkbox" checked autocomplete="off"> Checkbox3</span>
      </div>
    </div>
  </div>
</div>

Upvotes: 2

Manish Rane
Manish Rane

Reputation: 579

.outer-wrapper{
	height: 100vh;
	width: 100vw;
    overflow: hidden;
    position: fixed;
	background: transparent;
}

.container{
  position: fixed;
  width: 25vw;
  height: 40vh;
  top: 30vh;
  right: 0;
  background: #222;
  color: #FFF;
  padding: 20px;
}

.left{
 position:absolute;
 top:7%;
 left:-20%;
 background:red;
 height:10vh;
 padding:6px;
  	-webkit-transform: rotate(-90deg); 
	-moz-transform: rotate(-90deg); 
	-ms-transform: rotate(-90deg); 
	-o-transform: rotate(-90deg); 
	transform: rotate(-90deg);
}

.right{
  position: absolute;
  width: 80%;
  left: 20%;
}
<div class="outer-wrapper">
  <div class="container">
    <div class="left">
      <span>Menu</span>
    </div>
    <div class="right">
      <span><input type="checkbox" checked autocomplete="off"> Checkbox1</span><br>
      <span><input type="checkbox" checked autocomplete="off"> Checkbox2</span><br>
      <span><input type="checkbox" checked autocomplete="off"> Checkbox3</span>
    </div>
  </div>
</div>

Upvotes: -1

Related Questions