Arete
Arete

Reputation: 1004

Div float keep fixed and 100% height of the viewport

I am trying to make a basic responsive structure for a website with CSS. So far I have managed to make three column divs, a menu, a sidebar and one for content.

What I would like to achieve now is to have the menu and the sidebar to be 100% of the viewport height and fixed so that the content div is "scrollable" but the menu and the sidebar stays on top no matter how much content there is in the col content column. Naturally, I do not want this to happen in the media query though.

How can I achieve this most efficiently with CSS. Do I have to restructure the divs in HTML or is there any way to achieve this with CSS?

/*  SECTIONS  */

.section {
  clear: both;
}
/*  COLUMN SETUP  */

.col {
  display: block;
  float: left;
}
/*  GRID OF THREE  */

.menu {
  width: 33%;
  background-color: #98D2ED
}
.sidebar {
  width: 33%;
  background-color: #D3ADAD
}
.content {
  width: 33%;
  background-color: #C9E4D1
}
/*  GO FULL WIDTH BELOW 480 PIXELS */

@media only screen and (max-width: 480px) {
  .menu {
    width: 100%;
  }
  .sidebar {
    width: 100%;
  }
  .content {
    width: 100%;
  }
}
<div class="section">
  <div class="col menu">
    <p>
      Menu
    </p>
    I want this cloumn to be fixed and full height of the viewport when the screen size is above 480px.
  </div>
  <div class="col sidebar">
    <p>
      Sidebar
    </p>
    I want this cloumn to be fixed and full height of the viewport when the screen size is above 480px.
  </div>
  <div class="col content">
    Content
  </div>
</div>

What I am trying to achieve: enter image description here

enter image description here

Upvotes: 4

Views: 2572

Answers (2)

Stickers
Stickers

Reputation: 78796

You can use flexbox, either for known/unknown width and height elements, The key is to set the content area to overflow:auto, and switch the flex-direction to column in media queries.

jsFiddle

html, body {
  height: 100%;
}
body {
  margin: 0;
  display: flex;
}
.content {
  flex: 1;
  overflow: auto;
}
.menu    { background: grey;   }
.sidebar { background: silver; }

@media (max-width: 480px) {
  body {
    flex-direction: column;
  }
}
<div class="menu">Menu</div>
<div class="sidebar">Sidebar</div>
<div class="content">
  <!-- scroll test -->
  <div style="height:1000px;">Content</div>
</div>

Or, the traditional way to set the menu and sidebar to position:fixed.

jsFiddle

html, body {
  height: 100%;
  margin: 0;
}
body {
  margin-left: 200px;
}
.menu, .sidebar {
  position: fixed;
  top: 0;
  height: 100%;
  overflow: auto;
}
.menu {
  left: 0;
  width: 100px;
  background: grey;
}
.sidebar {
  left: 100px;
  width: 100px;
  background: silver;
}
.content {
  overflow: auto;
}
@media (max-width: 480px) {
  body {
    margin: 100px 0 0;
    overflow: hidden;
  }
  .menu, .sidebar {
    left: 0;
    width: 100%;
    height: 50px;
  }
  .sidebar {
    top: 50px;
  }
  .content {
    height: calc(100% - 100px);
  }
}
<div class="menu">Menu</div>
<div class="sidebar">Sidebar</div>
<div class="content">
  <!-- scroll test -->
  <div style="height:1000px;">Content</div>
</div>

Upvotes: 2

Emmet Arries
Emmet Arries

Reputation: 549

As I understand, you want your .menu and .sidebar to be stuck to the screen in one place and have the content be scrollable. And add some more code to other things as well, I know that sounds vague, but it would be a waste of time to write everything down, as I have edited you I finished copy, and I have notes that explain all my changes (and the reasons for doing so) in the code below.

I removed the floats and their classes, as I believe those are not necessary, and that the floats do more harm than good. As well as moved the .content to be in the middle column (between .menu and .sidebar). However, if you need to, feel free to change any or al of these things back.


Here's the updated code: (and here's a JSFiddle: JSFiddle)

I know that .menu has a weird space above it (when running the snippet and the JSFiddle), but I have it live on my website here, and it behaves perfectly fine, and uses the same code.

* {
	margin: 0px; /* Added to remove margin from everything */
	padding: 0px; /* Added to remove margin from everything */
}

.section, .menu, .sidebar, .content {
	display:inline-block !important; /* Added so they will line up next to each other */
}

.section {width:100%;} /* Pretty self explanatory, added to set ".section" to a width of 100% */

/*  GRID OF THREE  */
.menu {
	width: 33%; /* Was already here */
	background-color: #98D2ED; /* Was already here */
	
	height:100vh; /* Makes it be 100% of the Viewport Height, or 100% of the browser window height */
	
	position: fixed; /* Makes it stay "fixed" to one place on the screen */
}

.sidebar {
	width: 33%; /* Was already here */
	background-color: #D3ADAD; /* Was already here */
	position:absolute; top:0px; left: 67%; /* To make the element in the right place, add the width of "menu" and "content" */

	height:100vh; /* Makes it be 100% of the Viewport Height, or 100% of the browser window height */

	position: fixed; /* Makes it stay "fixed" to one place on the screen */
}
.content {
	width: 34%; /* Was already here, but changed it to 34 to make the website fill the page */
	background-color: #C9E4D1; /* Was already here */

	position:absolute; top:0px; left:33%; /* To make the element in the right place, make this the width of "menu" */
}


/* The CSS below this was already here */

/*  GO FULL WIDTH BELOW 480 PIXELS */
@media only screen and (max-width: 480px) {
  .menu { width: 100%; }
  .sidebar { width: 100%; }
  .content { width: 100%; }
}
<head>
    <link rel="stylesheet" type="text/css" href="style.css">
</head>

<div class="section">
    <div class="menu">
        Menu
    </div>
	<div class="content">
        Content
    </div>
    <div class="sidebar">
        Sidebar
    </div>
</div>

Really Hope that helped!

Upvotes: 2

Related Questions