Having columns stretch to footer under all circumstances?

This is my current code. It “works” except for when the left column has a taller content than the right one (as shown in this example.
Would greatly appreciate some help with this.

Hi, Roy_Bread, welcome to the forums.

Have you considered using display:table and display:table-cell properties to construct your columns? One of the beauties of that structure is that the table-cells remain equal heights.

Like this? (probably not)
Sorry. I don’t quite get it.

This is a “generic” two-column layout with a sticky footer demo page. The contents of the header and footer determine their height. There is no height assignment for any of the sections.

The left column has a fixed width at this time, however that can be change to a percent width if desired. A third column can be added easily.

I have over-classed the divs to make their function clear. You should economize or simplify the classnames so they are more meaningful to your page.

Colors and outlines are for testing purposes and are expected to be changed or deleted.

This layout technique was pioneered by our very own @PaulOB

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <title>2 col layout with sticky footer</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
<!--
https://www.sitepoint.com/community/t/how-to-fit-the-height-and-width/211562/6
-->
    <style>
html, body {
    margin:0;
    padding:0;
    height:100%;
}
body {background-color:#ccc;}
.outer {
    display:table;
    table-layout:fixed;
    width:100%;
    max-width:980px;  /* As Desired */
    height:100%;
    margin:auto;
    outline:1px solid red;
}
.content {
    display:table;
    width:100%;
    height:100%;
}
.trow {display:table-row;}
.tcell {
    display:table-cell;
    vertical-align:top;
    padding:10px;
}
.main.tcell {padding:0;}
.header,
.footer {
    height:1px;
    background-color:#def;
}
.main {
    background-color:#ffc;
    color:#444;
}
.leftcol {
    width:300px;
    background-color:#ace;
}
.rightcol {
    background-color:#eca;
}
h1 {text-align:center;}
.footer p {text-align:center;}
    </style>
</head>
<body>

<div class="outer">
    <div class="trow">
        <div class="header tcell">
            <h1>header and horizontal menu maybe</h1>
        </div>
    </div>
    <div class="trow">
        <div class="main tcell">
            <div class="content">
                <div class="leftcol tcell">
                    <p>LeftCol</p>
                </div>
                <div class="rightcol tcell">
                    <p>RightCol</p>
                </div>
            </div>
        </div>
    </div>
    <div class="trow">
        <div class="footer tcell">
            <p>Sticky Footer</p>
        </div>
    </div>
</div>

</body>
</html>
1 Like

Sweet. I’ll have a look at it and see if I can incorporate and understand it properly.
Thanks.

I wanted to look more into the table column thing earlier but found myself without access to the internet for a period of time shortly after posting.

1 Like

I don’t get this after all :confused:

Hi,

You made a few errors from Rons example.:slight_smile:

You missed out the display:table on the wrapper and the nested table for the columns. You used min-height for the table wrapper yet min-height doesn’t apply to display:table elements as they need height instead. Tables and display:table treat height as a minimum anyway and will always expand to encompass content should it be needed.

You misnamed the trow element to throw in some cases (not all).

The header and navigation was not in the cell and row structure and thus existed in a place where they can’t exist in that structure.

Here is the revised code in working order.

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<style>
html, body {
	font-family: Meiryo;
	font-size: 14px;
	margin: 0;
	padding: 0;
	height: 100%;
}
h1 {
	margin-bottom: 48px;
	font-size: 32px;
	text-align: center;
}
h2 {
	font-size: 18px;
}
a {
	text-decoration: none;
	color: inherit;
}
.trow {
	display: table-row;
}
.tcell {
	display: table-cell;
	vertical-align:top;
}
#wrapper {
	margin: 0 auto;
	height: 100%;
	max-width: 1080px;
	width:100%;
	display:table;
}
#header {
	height: 140px;
	background:red url(../img/logo.png);
}
/*-------Navigation-------*/
#navigation ul {
	font-size: 0;
	padding: 0;
}
#navigation li {
	width: 180px;
	height: 32px;
	display: inline-block;
	background: #ffc7e9;
}
#navigation a {
	display: block;
	text-align: center;
	line-height: 32px;
	font-size: 12px;
	font-weight: 800;
}
#navigation a:hover {
	color: white;
}
/*-------Navigation end-------*/

#left {
	padding: 10px;
	width: 220px;
}
.left-image {
	padding: 5px 7px 5px 0;
}
.right-image {
	padding: 5px 0px 5px 7px;
}
.contents {
	display:table;
	width:100%;
	height:100%;
}
#content {
	padding: 10px 20px 10px 20px;
	background: #DFDED4;
	text-align: center;
}
.cast {
	margin: 0 48px 96px 48px;
	background: white;
	text-align: center;
	border: 1px solid black;
	width: 100px;
	height: 128px;
	float: left;
}
.layer {
	transform: translateY(108px);
	height: 20px;
	line-height: 20px;
	background: rgba(255, 255, 255, 0.5);
	color: rgba(0, 0, 0, 1);
}
.modal-content img {
	margin: 0 20px 0 0;
	float: left;
}
.modal-content p {
	font-size: 14px;
}
/*-------Footer-------*/
#footer {
	width: 100%;
	background: #18121E;
	height:32px;
}
#footer p {
	font-size: 10px;
	text-align: center;
	line-height: 24px;
	color: white;
}
/*-------Modal-------*/
.lightbox .box {
	width: -webkit-min-content;
	width: -moz-min-content;
	width: min-content;
	min-width: 600px;
	margin: 2% auto;
	padding:20px;
	background-color: white;
	box-shadow: 0px 1px 26px -3px #777777;
	position: fixed;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%)
}
.lightbox .title {
	margin:0;
	padding:0 0 10px 0px;
	border-bottom:1px #ccc solid;
	font-size:22px;
}
.lightbox .content {
	display:block;
	padding:10px 0 0 0px;
}
.lightbox .close {
	float:right;
	display:block;
	text-decoration:none;
	font-size:22px;
	color:#858585;
}
.lightbox {
	display: none; /*Hide the lightbox*/
	position: fixed;
	width: 100%;
	height: 100%;
	bottom: 0;
	left: 0;
	color:#333333;
}
.lightbox:target {
	display: block; /*Show lightbox when it is target*/
	outline: none;
}
/*-------Cast Members-------*/
#rumi {
	background-image: url("../img/Rumi.jpg");
}
#underling {
	background-image: url("../img/Underling.jpg");
}
</style>
</head>

<body>
<div id="wrapper">
  <div class="trow">
    <div id="header" class="tcell">
      <div class="header-content goes-here">
        <h1>header</h1>
      </div>
      <div id="navigation">
        <ul>
          <li><a href="Index.html">Index</a></li>
          <li><a href="html/System.html">System</a></li>
          <li><a href="html/Cast.html">Cast</a></li>
          <li><a href="html/Schedule.html">Schedule</a></li>
          <li><a href="html/Access.html">Access</a></li>
          <li><a href="html/Contact.html">Contact</a></li>
        </ul>
      </div>
      <!--navigation--> 
    </div>
    <!-- end tcell header --> 
  </div>
  <!-- end trow -->
  <div class="trow">
    <div class="tcell">
      <div class="contents">
        <div id="left" class="tcell"> <a class="twitter-timeline" href="https://twitter.com/Roy_Bread" width="220px" height="397px" data-widget-id="728961573411119106">Tweets by @Roy_Bread</a> 
          <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script> 
          <a href="#"><img class="left-image" src="img/Twitter.png" alt="Twitter" width="100" height="100"></a> <a href="#"><img class="right-image" src="img/Facebook.png" alt="Facebook" width="100" height="100"></a> </div>
        <!--left-->
        
        <div id="content" class="tcell">
          <h1>ようこそ!</h1>
          <h2>[コンセプトの説明]</h2>
          <h2>[店の画像]</h2>
          <h2>[時事]</h2>
        </div>
        <!--content--> 
      </div>
      <!-- end contents --> 
    </div>
  </div>
  <div class="trow">
    <div id="footer" class="tcell">
      <p>Copyright © 店名 2016 All rights reserved.</p>
    </div>
    <!--footer--> 
  </div>
</div>
<!--wrapper-->
</body>
</body>
</html>

If you look at that code the changes should be obvious but just shout if anything is not clear.

3 Likes

Writing “trow” as “throw” would negate most effects for sure.
My fingers must’ve auto-corrected it to the nearest real English word :V
Thanks. I went over the code and can see the logic now.
It’s not as simplistic as I’d have liked for it to be (thought I could do this with 6 divs) but if it works it works, I suppose.

One last thing though (hopefully). With this new code (https://jsfiddle.net/xeL98xpk/)(should be the same except for naming and wrapper width) a gap appears between the navigation and the content when the view-port is sufficiently tall. Why’s this? Going over the code I’m not spotting anything that’d seemingly cause this.

If you check the code I gave above you will see that this problem does not occur.

The problem in your code is that you wrapped header and navigation in one cell (which is fine) but you omitted to confine the height of that cell to 1px.

Table-cells must always fill a table so if you have three rows in a table then those rows must stretch to the 100% height of the table. They do this automatically and so when the height stretches all the rows stretch also. In both mine and Ron’s example we made sure that the header and footer had a fixed height by default and that means that the rest of the page is occupied by the middle section. The top and bottom of the page will only be as tall as the contents they hold because as I said in my other post height is treated as a minimum as far as tables and table-cells are concerned.

So you answer your question you just need to add a 1px height here.

<div id="wrapper">
  <div class="trow">
    <div class="tcell top">

.top{height:1px}

It’s pretty simple in essence and follows a normal table structure. You could do this with flexbox if you only want to support modern browsers but the table version should work back to ie8 (although there may be issues with the middle columns in older IE not reaching 100%they should not affect function).

That fixed it, but now the footer is taller than the assigned 32px despite the entire page being filled.

That might be because the footer lost it’s height:1px, too I believe you have set a taller height on the footer which should not be there (32px you just said). The height of the top cell and the bottom cell must be 1px. The cells will expand to accommodate taller content.

Actually it seems that the table automatically centers the text vertically, so the assigned line-height just added extra height.

line-height is assigned to a paragraph, height is assigned to the footer. It’s the footer that should have a height of 1px assigned.

I mean I had a 32px line-height remaining that I used to center the paragraph before changing to a table layout.

New problem though. With this new code (https://jsfiddle.net/63c1to60/) the thing works in fullscreen but vertical scroll bars appear when the window is down-sized despite all the content showing.

Show me the code. Never mind, I see the link to the fiddle. :blush:

Why do you have all of that white space above the menu?

What is the problem with the code that Paul posted in #7? Yours is different. The menu and the logo header must be within that 1px header table-cell (like Paul’s code shows). Yours is not.

Logo (header).

If I recall correctly, doing so pushed the menu out of the wrapper and somehow made the links stack vertically. Or it caused white space to appear in between the header, menu and content. I’ll have another look at it. Might’ve messed something up again.

This layout is structured very simply.

The page as one outer table,
That table has three rows,
Each row has one table-cell.

The header and probably the menu go into the top (header) table-cell.
The content goes into the middle table-cell.
The footer info goes into the footer table-cell.

Copy the code that I posted to a new file and give it a an html suffix. Open it in your browser. There is no stray white space anywhere and no scroll bars. Your content needs to go inside those colored table-cells. You can’t break any of those cells into rows.

My bad. It works with the current CSS. The scroll bar is still there though.