Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Three-row table-less CSS layout with middle-row that fills remaining space

Tags:

css

What I need is a div with pixel-based height containing 3 rows. The top row has variable height depending on the contents. The bottom row has a fixed height. The middle row fills any remaining space. Everything is width 100%.

I've been struggling with constructing a div and CSS-based layout for hours that takes me literally seconds to do using a table. I've tried many approaches including negative bottom margins, nesting divs, various positionings, height settings, display:table, nothing gets me what I need. I've searched this site and the internet, refreshed my memory of the various approaches for liquid layouts. No avail.

I'm not especially worried about compatibility with "old" browsers like IE6 (this app isn't for "public" use). Just getting this to work in IE8+FF+Chrome would be great.

I've stripped the problem to a bare example posted below, along with the table-based layout showing what I want. Sidenote: I love CSS and table-less layout, but, sometimes it just seems ridiculous the lengths we have to go through to make it work.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<style type="text/css">
.container {width:500px;height:200px;border:1px solid black;background-color:#c0c0c0;position:relative;}

/* Styles for colors */
#top td, .top {width:100%;background-color:pink;}
#mid td, .mid {width:100%;background-color:lightgreen;border:1px solid red;}
#bot td, .bot {width:100%;background-color:lightblue;}

/* Styles for Table-based Layout */
#layout {width:100%;height:100%;border-collapse:collapse;}
#layout td {vertical-align:top;padding:0px;}
#top td {}
#mid td {height:100%;}
#bot td {height:2em;}

/* Styles for Table-less Layout */
.top {}
.mid {}
.bot {height:2em;position:absolute;bottom:0px;}

</style>
</head>
<body>

Layout I want (with tables):
<div class="container">
  <table id="layout">
    <tr id="top"><td>Top:<br/>Content-based<br/>Height</td></tr>
    <tr id="mid"><td>Middle:<br/>Fill remaining space</td></tr>
    <tr id="bot"><td>Bottom: Fixed Height</td></tr>
  </table>
</div>

<hr/>

Best I can get with CSS:
<div class="container">
  <div class="top">Top:<br/>Content-based<br/>Height</div>
  <div class="mid">Middle:<br/>Fill remaining space</div>
  <div class="bot">Bottom: Fixed Height</div>
</div>

</body>
</html>

Meanwhile, I couldn't let this stop my progress, spent too much time already. I'm going ahead with the table layout in my project. It's simple and fully satisfies the requirements, even if the purists are wailing somewhere.

Thanks for any suggestions though - I'm mainly curious what the "right" solution is at this point, I hate being stumped. Surely, it's doable?

like image 309
Joe Tan Avatar asked Nov 09 '09 20:11

Joe Tan


People also ask

How to make a Div fill the remaining space in CSS?

Another way of making a <div> fill the remaining space is to use the CSS position property. Just set the position to “absolute” to stretch the <div>. 3. The next method of making a <div> fill the remaining space is using tables. By setting the display property to “table”, we can distribute the given space.

What is CSS grid layout?

Grid Layout The CSS Grid Layout Module offers a grid-based layout system, with rows and columns, making it easier to design web pages without having to use floats and positioning.

Should tables be used in HTML for layout purposes?

It has been advocated many times that tables shouldn't be use in HTML for layout purposes. This page shows one way to create a 3 columns layout using CSS only. Please send comments and suggestions to Dominique Hazaël-Massieux. Translations of this article are available.

What is the gap between grid rows and columns called?

The horizontal lines of grid items are called rows. The spaces between each column/row are called gaps. The grid-column-gap property sets the gap between the columns:


1 Answers

The key to your problem is looking at the problem differently -- if you Google "sticky footer" you'll find solutions like the following:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<style type="text/css">
.container {width:500px;height:200px;border:1px solid black;background-color:#c0c0c0;position:relative;}

.notbottom2 {
    min-height: 100%; background-color:lightgreen; width: 100%;
    height: auto !important;
    height: 100%;
}

.mid2 {padding-bottom: 2em;}
.top2 { width: 100%;  background-color: pink;}
.bottom2 { height: 2em; width: 100%; margin-top: -2em; background-color: lightblue; }

</style>
</head>
<body>
<div class="container">
<div class="notbottom2">
    <div class="top2">Top:<br/>Content-based<br/>Height</div>
    <div class="mid2">Middle:<br/>Fill remaining space</div>
</div>
<div class="bottom2">Bottom: Fixed Height</div>
</div>
</body>
</html>

EDIT: there, this should be what you want, more or less.

like image 100
Walter Mundt Avatar answered Oct 19 '22 23:10

Walter Mundt