37

I know this is a sort of a common problem, and I looked up some solutions, but couldn't find exactly what I was looking for.

I would like to convert this to a tableless layout.

enter image description here

Note: header and footer have to be set to a fixed height in pixels (50px is ok).

The main problem I'm having is that I cannot get that "big box" in the middle to behave like it does when it's done with tables. There are solutions which work OK for a variable length content (text, images), but I would like this box look and behave like a box - with borders, rounded corners and all.

Madara's Ghost
  • 172,118
  • 50
  • 264
  • 308
ile
  • 1,765
  • 1
  • 16
  • 19
  • http://stackoverflow.com/questions/485827/css-100-height-with-padding-margin – Jith May 28 '11 at 01:06
  • http://stackoverflow.com/questions/172918/div-100-height-works-on-firefox-but-not-in-ie-what-to-do – Jith May 28 '11 at 01:06
  • Here's an more example: http://www.reallinks.org/DIV-Header-Layout-100-Height/ + 2 Colummns / Left and Right –  Sep 20 '12 at 12:08

3 Answers3

47

You can do it with table style CSS properties, but still retain table less markup (which is still a win).

Example

Example

HTML

<div id="container">
    <div id="header"><div>header</div></div>
    <div id="content"><div>content</div></div>
    <div id="footer"><div>footer</div></div>
</div>

CSS

html,
body {
    height: 100%; 
    padding: 0;
    margin: 0;
}

#container {
    display: table; 
    width: 100%;
    height: 100%;
    border: 1px solid red;   
    text-align: center;
}

#container > div {   
    display: table-row;   
    width: 100%;
}

#container > div > div {   
    display: table-cell;   
    width: 100%;
    border-radius:10px; 

}

#header > div {
    height:50px; 
    border:solid 2px #aaa;
}

#content > div {
    height: 100%;    
    background:#f0f4f0; 
    border:solid 2px #5a5;
}

#footer > div {
    height:50px; 
    border:solid 2px #a55;
}

jsFiddle.

alex
  • 479,566
  • 201
  • 878
  • 984
  • Oh, yes, I think I can :) That's pretty great. Thanks for the quick solution. – ile May 28 '11 at 01:09
  • Table-styles are not very well supported in older browsers, if that matters to you. – Ben Hull May 28 '11 at 01:13
  • Well, it doesn't matter to me (I require WebSockets anyway), but if someone comes up with an alternative answer, that might help others. It might be even better and earn some love in the form of points. – ile May 28 '11 at 01:15
  • 3
    @Beejamin Not supported in < IE8, unfortunately. – alex May 28 '11 at 01:15
  • @Alex - that's true. Also, and it doesn't apply to your example specifically, but Webkit browsers also require you to have your `display:table-cell;` elements wrapped in a `display:table-row;` and `display:table;` element. I guess that makes sense, but it's not always convenient to rely on having two layers of wrappers! Good answer, mate - +1 from me. – Ben Hull May 28 '11 at 01:20
  • Note that the content box doesn't have a fixed height in this solution. It will resize to accommodate a tall image in it, for example. – Dan Dascalescu Aug 18 '12 at 10:06
  • Is this really table-less layout? – drinchev May 09 '13 at 18:13
  • 1
    @drinchev Well, they're styled like a table but the markup doesn't consist of tables. Call it what you want. – alex May 09 '13 at 21:10
  • just a small addition: add `* {box-sizing: border-box}` to get rid of the 2px offset due to the border – scheffield Mar 29 '14 at 21:43
29

'Multiple absolute co-ordinates' is a nice way to achieve this. This is when you absolutely position a box, then give it both top and bottom co-ordinates. Without specifying a height, you get a box which wants to be 10px from the top, and 10px from the bottom edges of its parent.

Here's an example

There is an IE6 specific style you'll need to add, if you care about that browser.

Here's an article on the technique (plus the IE6 fix) - it's a good one to know, even if you don't use it for this problem.

SingerOfTheFall
  • 29,228
  • 8
  • 68
  • 105
Ben Hull
  • 7,524
  • 3
  • 36
  • 56
  • 1
    Well, actually I think this is even better - less markup and no specific table like remnants. I was too quick to promote the answer, so I'm very sorry but I think I have to change it to this. Didn't expect that there would be another solution. – ile May 28 '11 at 01:24
  • Worked perfectly for the app (single screen chat application). Thank you. – ile May 28 '11 at 01:50
  • Excellent solution, and so simple when you think about it! – Dan Dascalescu Aug 18 '12 at 09:26
  • Wow! This is actually a much simpler way to do this! Nice answer! – sarahholden Jun 19 '14 at 23:32
1

You haven't said anything about heights of your sub elements, so I have had to make some presumptions. You could use percentages if you wanted.

<style>
html,body {margin:0;padding:0;
}
#mainContainer {
height:100%;
width:100%;
}

#header {
height:15%;
width:100%;
background-color:red;
}

#center {
height:75%;
width:100%;
background-color:blue;
}

#footer {
height:10%;
width:100%;
background-color:pink;
}
</style>

    <body>
    <div id="mainContainer">
    <div id="header">Header</div>
    <div id="center">Center</div>
    <div id="footer">Footer</div>

</div>

    </div>
    </body>
Layke
  • 51,422
  • 11
  • 85
  • 111
  • Yes, agreed - I edited the question. They really need to be fixed height (like 50px). – ile May 28 '11 at 01:02
  • 3
    This wouldn't work anyway. Percentage heights require the parent container to have a specified height. When the parent does not have a specified height, then height:100% is treated as height:auto. http://jsfiddle.net/ajVSd/1/ – Brent Friar May 28 '11 at 03:20
  • @Layke can you take a look at http://stackoverflow.com/questions/30106602/how-to-make-image-stretch-to-a-specific-paragraph ? – committedandroider May 07 '15 at 18:00