10

I am trying to create a head area that is 100px in height and spans 100% in width. I need 2 columns with the left one being 250px wide and 100% in height down to the footer. The right column should be 100% of the remaining page width and 100% in height to the footer. The footer should be at the bottom of the page and 100px in height and 100% in width. Even if there is no content in the 2 columns, I need them to stretch down to the footer and have the footer visible without scrolling down to it.

Here is what I have so far.

<div id="top"><p>Lorem ipsum dolor sit amet</p></div>
<div id="left"><p>Lorem ipsum dolor sit amet</p></div>
<div id="right"><p>Lorem ipsum dolor sit amet</p></div>
<div id="bot"><p>Lorem ipsum dolor sit amet</p></div>

body, html {
    height: 100%;
}
body {
    margin: 0px;
}
p {
    margin: 0px;
}
#top {
    height: 100px;
    background-color: #F4F4F4;
}
#left {
    width: 250px;
    height: 100%;
    background-color: #878787;
    float: left;
    margin-bottom: -100px;
}
#right {
    background-color: #323232;
    height: 100%;
    margin-bottom: -100px;
}
#bot {
    clear: right;
    height: 100px;
    background-color: #DCDCDC;
    margin-top: -100px;
    z-index: 100;
    position: relative;
}

Here is another example with a table

<table height="100%" width="100%" cellspacing="0" cellpadding="0" border="0" class="" id="">
	<tr>
		<td colspan="2" style="background-color: powderblue; height: 100px;">Header</td>
	</tr>
	<tr>
		<td style="background-color: gray; width: 350px;">Left Col</td>
		<td style="background-color: DarkSeaGreen">Right Col</td>
	</tr>
	<tr>
		<td colspan="2"  style="background-color: tomato; height: 100px;">Footer</td>
	</tr>
</table>

enter image description here

2

9 Answers 9

7
+50

Here is a simple CSS-grid solution (I used 50px instead of 100px so we can see it in the reduced snippet)

html {
    height: 100%;
}
p {
    margin: 0px;
}
body {
  min-height:100%;
  margin:0;
  display:grid;
  grid-template-rows:50px 1fr 50px;
  grid-template-columns:250px 1fr;
  grid-template-areas:
    "top top"
    "left right"
    "bot bot";
}

#top {
    grid-area:top;
    background: linear-gradient(#F4F4F4,blue);
}
#left {
    grid-area:left;
    background: linear-gradient(#878787,red);
}
#right {
    grid-area:right;
    background: linear-gradient(#323232,green);
}
#bot {
    grid-area:bot;
    background: linear-gradient(#DCDCDC,purple);
}
<div id="top"><p>Lorem ipsum dolor sit amet</p></div>
<div id="left"><p>Lorem ipsum dolor sit amet</p></div>
<div id="right"><p>Lorem ipsum dolor sit amet</p></div>
<div id="bot"><p>Lorem ipsum dolor sit amet</p></div>

And here is with flexbox:

body, html {
    height: 100%;
}
p {
    margin: 0px;
}
body {
  margin:0;
  display:flex;
  flex-wrap:wrap;
}

#top,#bot {
    height:50px;
    width:100%;
    background: linear-gradient(#F4F4F4,blue);
}
#left {
    width:250px;
    min-height:calc(100% - 2 * 50px);
    background: linear-gradient(#878787,red);
}
#right {
    flex:1;
    min-height:calc(100% - 2 * 50px);
    background: linear-gradient(#323232,green);
}
<div id="top"><p>Lorem ipsum dolor sit amet</p></div>
<div id="left"><p>Lorem ipsum dolor sit amet</p></div>
<div id="right"><p>Lorem ipsum dolor sit amet</p></div>
<div id="bot"><p>Lorem ipsum dolor sit amet</p></div>

Sign up to request clarification or add additional context in comments.

8 Comments

It looks like in the flex example when you have excess content in the $right div it runs over the $bot div and does not push it down. The grid example is the SOLUTION!
@drooh in this case you can add overflow:auto to each div to avoid overlap ;)
Looks like adding overflow:auto to each left and right div causes the footer to stay in place and the text goes behind it.
@drooh so if the content exceed you want the layout to be more than 100% height of the viewport?
yes, that is correct. The CSS Grid answer you provided appears to be the best overall solution I've read. The next best that actually fully works is using the table method.
|
0

You could use the Sticky Footer Concept: Sticky Footer

* {
    margin: 0;
}
html, body {
    height: 100%;
}
.wrapper {
    min-height: 100%;
    height: auto !important;
    height: 100%;
    margin: 0 auto -155px; /* the bottom margin is the negative value of the footer's height */
}
.footer, .push {
    height: 155px; /* .push must be the same height as .footer */
}

The Result would look like this: Working Fiddle

But stretching the columns without content to the bottom is not possible without javascript. Why would you want to do that anyways?

3 Comments

Because the background color is part of the design and it needs to extend down to the footer.
@drooh: Consider adding a background image to the body that is 250px wide and the color of your left column. Repeat y only. Set the background color of the body to the right column's desired color. Now there's no need to extend the divs to the bottom.
this is prob the answer, just wanted to avoid having to use an image when its just a solid color, but obviously this would be an easy solution
0

Try This

#bot {
clear: right;
background-color: #DCDCDC;
position:absolute;
bottom:0;
width:100%;
z-index: 100;
margin-bottom: 0px;
}

Working Fiddle

Comments

0

In those cases, I recommend position: fixed or absolute. It works just like calc(), but in old browser too!

Demo

#top, #left, #right, #bot {
    position: fixed;
}
#top {
    top: 0;
    left: 0;
    right: 0;
    height: 100px;
}
#left, #right {
    top: 100px;
    bottom: 100px;
}
#left {
    width: 250px;
    left: 0;
}
#right {
    left: 250px;
    right: 0;
}
#bot {
    height: 100px;
    bottom: 0;
}

It would also be a good idea (in case browser window is too small), to also use

html, body {
    height: 100%;
    position: relative;
    min-height: 300px; /* Minimum height */
    margin: 0;
}
#top, #left, #right, #bot {
    position: absolute;
}
#left, #right {
    overflow: auto; /* Enable scrollbars if necessary*/
}

Demo

3 Comments

My only downside to this solution would be that it is static in the browser window. Be careful if your content overflows, because fixed won't solve that (see here: jsfiddle.net/83LBA/1)
@NicholasHazel Yeah, I was working on it. Anyway, my solution does exactly what OP asked. Only that he didn't define what should happen in a degenerate case where browser window isn't tall enough.
I need the content in the left or right column to push the footer down when excess content is in them
0

Use calc(). It's awesome.

DEMO *FullscreenDEMO*

<div class="head">header</div>
<div class="left">left</div>
<div class="right">right</div>
<div class="foot">footer</div>

   *{
    margin:0;
}
html,body{
    height:100%;
}
.head,.foot{
    width:100%;
    height:100px;
    background-color:red;
}
.left{
    width:250px;
    min-height:calc(100% - 200px);
    background-color:blue;
    display:inline-block;
    float:left;
}
.right{
    width:calc(100% - 250px);
    min-height:calc(100% - 200px);
    background-color:green;
    display:inline-block;
    float:left;
}
.foot{
    float:left;
}

7 Comments

Yet again, there is a downside. Make sure your content doesn't overflow: jsfiddle.net/fcVPH/1
I am pretty sure that can be sorted out. Here. Besides I am certain left panel would be used for a menu. And calc() is there to only help when there isn't enought content to fill up the space.
Is there a way to make it push the footer down?
this is very close but then the right col doesn't stretch down. seems like something like this shouldn't be this difficult?
@drooh: It will stretch when you open it in a normal viewport. Check THIS
|
0

http://codepen.io/anon/pen/jhCed

Bonus: stretched left column background of 100%.

  <div id="page">
    <div id="top"><p>Lorem ipsum dolor sit amet</p></div>
    <div id="content">
      <div id="left"><p>Lorem ipsum dolor sit amet</p></div>
      <div id="right"><p>Lorem ipsum dolor sit amet</p></div>
    </div>
  </div>
  <div id="bot"><p>Lorem ipsum dolor sit amet</p></div>

 html,body {
  margin: 0;
  padding: 0;
  height: 100%;
}
p {
    margin: 0px;
}
#page {
  position: relative;
  min-height: 100%; 
}
#page:before{
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  z-index: -1;
  height: 100%;
  width: 250px;
  background-color: #878787;
}
#page:after {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  z-index: -2;
  height: 100%;
  width: 100%;
  background-color: #323232;
}

#content {
  overflow: hidden;
  padding-bottom: 100px;
}
#top {
    height: 100px;
    position: relative;
    background-color: #F4F4F4;
}
#left {
    width: 250px;
    float: left;
    position: relative;
}
#right {
  margin-left: 260px;   
}
#bot {
    position: relative;
    margin: -100px auto 0 auto;
    height: 100px;
    background-color: #DCDCDC;
}

4 Comments

Your content flows into the left menu. You might wanna check that.
Nope. content still flowing into left div.
It does not since the padding-bottom fixes that.
Great. Believe what you want.
0

You could use flex

Here's a working example:

http://jsfiddle.net/6Mp4g/2/

Flex is a newer CSS3 workaround to creating stretched and responsive-like layouts for content. It can get a bit complicated, so I'll just link to the source and some syntax how-to:

https://developer.mozilla.org/en-US/docs/Web/CSS/flex

HTML:

<header>
    <h1>Header</h1>
</header>
<section class="Middle">
    <div class="LeftMenu">
        <h1>Left Menu</h1>
    </div>
    <div class="Content">
        <h1>Content</h1>
    </div>
</section>
<footer>
    <h1>Footer</h1>
</footer>

CSS:

*
{
    margin: 0;
    padding: 0;
}
html, body
{
    height: 100%;
    text-align: center;
}
body
{
    display: -webkit-flex;
    display: -ms-flexbox;
    display: flex;
    -webkit-flex-direction: column;
    -ms-flex-direction: column;
    flex-direction: column;
}
.Middle
{    
    -webkit-flex: 1 1 auto;
    -ms-flex: 1 1 auto;
    flex: 1 1 0;
    display: -webkit-flex;
    display: -ms-flexbox;
    display: flex;
    overflow: hidden;
}
.Content
{   
    -webkit-flex: 1 1 auto;
    -ms-flex: 1 1 auto;
    flex: 1 0 0;
    overflow: auto;
}
header
{
    background-color: #AAA;
    height:100px;
}
.LeftMenu
{
    background-color:  #CCA;
    width:250px;
}
.Content
{
    background-color: #CCF;
}
footer
{
    background-color: #AAA;
    height:100px;
}

1 Comment

It's getting screwed up when content overflows. Specially left menu.
0

Ok, here is an alternative using css tables. It works like this:

  • #top and #bot are always 100px tall.
  • #left will be 250px wide if it can.
  • #right occupies all horizontal space left by #left
  • #left and #right push #bot down.
  • If there is vertical remaining space, #left and #right will grow so that #bot will be at the bottom of the window.

Demo

html, body {
    height: 100%;
    width: 100%;
    margin: 0;
}
body {
    display: table;
}
#top, #bot {
    display: table-row;
}
#top {
    height: 100px;
}
#middle {
    display: table-cell;
    overflow: hidden;
}
#left, #right {
    margin-bottom: -100000px;
    padding-bottom: 100000px;
}
#left {
    width: 250px;
    float: left;
}
#right {
    overflow: hidden;
}
#bot {
    height: 100px;
}

It requires changing your html to

<div id="top"></div>
<div id="middle">
    <div id="left"></div>
    <div id="right"></div>
</div>
<div id="bot"></div>

Instead of 100000px, use a value greater than the height of #left and #right.

Since it's a bit hacky, you may prefer a css-tabular-only approach without floats, but doesn't work on IE8, although it only uses CSS2.1 features.

3 Comments

Oh this is a good one. But you might wanna check your top and bottom. They don't stretch to 100%
My bad. Mine is chrome 33.0.1750.146 m and here is a screenshot.
@LokeshSuthar My screen was to bright and I couldn't see the background :) Now it's really fixed.
0

This is my solution using grid. You need to have two nested grids to always show bottom grid item, even when content overflows.

This uses backward compatible -ms-code

body, html {
  height: 100%;
}

body {
  height: 100%;
  /* Define a grid with top and bottom each 100 pixel height */
  /* MSIE */
  display: -ms-grid;
  -ms-grid-columns: 1fr;
  -ms-grid-rows: 100px 1fr 100px;
  /* Modern browsers */
  display: grid;
  grid-template-rows: 100px 1fr 100px;
}

#top {
  /* This grid item takes the first row */
  /* MSIE */
  -ms-grid-row: 1;
  -ms-grid-row-span: 1;
  /* Modern browsers */
  grid-row: 1 / span 1; /* Shorthand for grid-row-start: 1; grid-row-end: span 1;*/
}

#center {
  /* This grid item takes the second row */
  /* MSIE */
  -ms-grid-row: 2;
  -ms-grid-row-span: 1;
  /* Modern browsers */
  grid-row: 2 / span 1; /* Shorthand for grid-row-start: 2; grid-row-end: span 1;*/
  overflow: auto;

}
#bot {
  /* This grid item takes the third row */
  /* MSIE */
  -ms-grid-row: 3;
  -ms-grid-row-span: 1;
  /* Modern browsers */
  grid-row: 3 / span 1;  /* Shorthand for grid-row-start: 3; grid-row-end: span 1;*/
}

#center {
  /* Define a grid with 250px width column and auto width column */
  /* MSIE */
  display: -ms-grid;
  -ms-grid-rows: auto;
  -ms-grid-columns: 250px 1fr;
  /* Modern browsers */
  display: grid;
  grid-template-columns: 250px 1fr;
}

#left {
  /* This grid item uses first column */
  /* MSIE */
  -ms-grid-column: 1;
  -ms-grid-column-span: 1;
  /* Modern browsers */
  grid-column: 1 / span 1; /* Shorthand for grid-column-start: 1; grid-column-end: span 1;*/
}

#right {
  /* This grid item uses second column */
  /* MSIE */
  -ms-grid-column: 2;
  -ms-grid-column-span: 1;
  /* Modern browsers */
  grid-column: 2 / span 1; /* Shorthand for grid-column-start: 2; grid-column-end: span 1;*/
}

/*
 * The span 1 parts could be omitted, as that is the default value for grid-(row|column)-end 
 */


/* Styling */
body {
  margin: 0;
}

#top, #bot {
  background: blue;
}

#left {
  background: red;
}

#right {
  background: green;
}
<div id="cont"></div>
  <div id="top">#top</div>
  <div id="center">
    <div id="left"><p>Lorem, ipsum dolor.</p>
    <p>Nisi, ducimus laudantium.</p>
    <p>Alias, tempore sapiente.</p>
    <p>Deleniti, rerum harum.</p>
    <p>Impedit, fugiat accusantium?</p>
    <p>Nulla, ipsam placeat.</p>
    <p>Itaque, incidunt doloribus.</p>
    <p>Voluptas, saepe soluta?</p>
    <p>Cum, possimus repellendus.</p>
    <p>Quaerat, sed numquam!</p>
    <p>Soluta, illo qui.</p>
    <p>Officiis, id qui.</p>
    <p>Tempora, perspiciatis ab.</p>
    <p>Asperiores, cupiditate minus!</p>
    <p>Molestiae, aut voluptatem?</p>
    <p>Inventore, odit quisquam.</p>
    <p>Veritatis, impedit possimus.</p>
    <p>Quia, facilis facere.</p>
    <p>Aperiam, quaerat minus.</p>
    <p>Accusantium, quos voluptate.</p>
    <p>Deserunt, accusantium cum.</p>
    <p>Culpa, assumenda explicabo.</p>
    <p>Dolorem, optio? Esse?</p>
    <p>Doloremque, expedita libero!</p>
    <p>Vero, aperiam? Nulla.</p>
    <p>Ullam, blanditiis ad.</p>
    <p>In, suscipit quos.</p>
    <p>Dicta, voluptates quos?</p>
    <p>Et, nam dolores!</p>
    <p>Magni, dolorem aut.</p>
    <p>Tenetur, reiciendis in?</p>
    <p>Rerum, aliquam totam!</p>
    <p>Nihil, deserunt culpa.</p>
    <p>Maxime, eveniet tempora?</p>
    <p>Unde, corporis harum?</p>
    <p>Corporis, dolore voluptatem.</p>
    <p>Consequuntur, ipsam corporis!</p>
    <p>Aperiam, labore iste!</p>
    <p>Voluptatibus, illum quia.</p>
    <p>Facere, nostrum voluptatem.</p></div>
    <div id="right">#right</div>  
  </div>
  <div id="bot">#bot</div>  
<div></div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.