Sticky Footer question

As an Opera user, yeah, we’re around. Most useful browser out of box and I think it’s more expandable than even the browsers that allow plugins – at least when it comes to useful stuff. You couldn’t pay me to use firefox as my primary daily use browser given what a buggy unstable CPU chewing train-wreck it is, hence my restricting it to just testing for page compatibility … and chrome doesn’t do anything useful for me even WITH extensions.

WinCE/Win Mobile since version 6 has been IE6, so IE6 is ‘new’ to windows mobile for only two years. Prior to two years ago every WinCE/Mobile device was STILL RUNNING IE 5.5!

This is just part of why I still code so that the pages at least work in 5.5, and behave properly in IE6. The other part being at this point it takes little or no effort to support either of them if you follow a few basic rules.

Those rules being:

  1. If a element’s children have positioning on them, trip haslayout on that parent.

  2. NEVER declare width and height the same time as padding or border on the same dimension.

  3. Use * html and expressions sparingly. The only legitimate need for either of those should be in implementing the bits of CSS 2.1 that are missing from IE6; specifically min/max-width/height… and, uhm… yeah. That’s really it for the list. Likewise for behavior files on things like :hover anywhere and, uhm… yeah.

  4. If you find yourself needing to hack for every browser or multiple versions of newer IE (IE7/IE8) your code is fundamentally flawed, try to find another way of coding it or rethink your layout as non-viable.

  5. Just because you can draw it in your goof assed paint program doesn’t make it a viable layout concept. IF you are DUMB ENOUGH to be starting from a PSD, be ready to throw out large sections of the design as bad ideas made by people who know jack about accessibility, standards or coding. This is why the artsy type should be the last person in the process, NOT the first - and should be prepared to be told “NO” on a lot of their non-viable for web/screen deployment ‘ideas’

*** Okay, here is where I am particularly confused… ***

Your article mentions that we “attach” the absolute column to the bottom of our “containing block” (i.e. relative div) but here I see you using:

position: absolute;
top: 0;
bottom: 0;

You specifically said…

[QUOTE]This technique is based on the fact that if you place an absolute element inside a relative container and set the absolute element to height:100% (or top:0 and bottom:0) it will expand in tune with the parent container…
…but I don’t understand what this does and it seems contradictory when you mention height:100% (or top:0 and bottom:0)[/QUOTE]height:100% is not necessary when using top & bottom together. It is basically the same thing so there is no need to set the height.

You then go on to say later in your article…

[QUOTE]
Instead we are going to place the absolute element at the bottom of the relative parent and give it a height of 1000em. Now instead of the absolute element going down the page it starts at the bottom of our columns and travels up the page and out the top of the browser window.
…but I don’t see that in the block of code above or anywhere?!

(In my opinion) This needs to be re-written and explained better![/QUOTE]The em height with bottom:0 is for IE6. That is done because IE6 does not understand top and bottom together on an AP element.

#three{
    clear: both;
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    width: 150px;
    background: #D685AD;
}

More of the same, however, why are we NOT doing this for Column #2???

How is it that Column #2 expands the full height of the browser window when it doesn’t have its own absolute column to do a background color?!

Column#2 gets it’s BG color from the wrapper div so there is no need for a faux div to color it.

/* IE6 FIX */
* html #one,
* html #three{
        height: 9999em;
        top: auto;
}

Maybe this has something to do with above, but if you could explain it in detail it would help me to know what purpose it serves and what it actually does?!
Yes, I explained that above. It is for IE6, the height is set in em for an outrageous height and the top value is set to auto so it positions at bottom:0; instead. Good browsers get top:0; and bottom:0; then the top:0 gets canceled out for IE6 so it obeys bottom:0;

WHEW!!! You made it!!

Sorry for all of the questions, but this is actually trickier than it initially looks, and I am seriously about REALLY LEARNING this stuff, so your detailed responses are greatly appreciated!!!

Whew is right! :slight_smile:
Good questions though

^ That margin/padding method from the “One True Layout” has one major problem with it (among others).

Linking to an anchor in any of the columns within the element that has been set to overflow: hidden causes the content of that column to shift upwards. In IE and Firefox, that is.

It is for that reason that we don’t recommend using it. :wink:

Yes, if you don’t have “in page links” then you could probably get away with it and it is a clever method.:slight_smile: However most sites do have some “in page” links and therefore is not really a “safe” solution for all but a useful technique to know all the same.

That would be me.

Likely referring to my example:
http://www.cutcodedown.com/for_others/tomtees/template.html

and it’s over-documented CSS
http://www.cutcodedown.com/for_others/tomtees/screen.css

P.S. Why is something that is visually so simple, so difficult to do and understand on the web?! GEESH!!!

Equal columns is a designers “eye” looking at things but in most cases we don’t need to do that. CSS is all about the content taking control rather than putting content in a cage.

Who says that if you have three columns then they all need to be the same height?

Equal columns is a left over from the table age because that’s the only way table cells work and designers had no choice but to make columns equal. CSS on the other hand frees your from this constraint. Columns can be as long as they need to be.

There’s often a trade-off between keeping things simple and at the same time trying to make then look good. A good designer can create great looking sites without needing to resort to tricks like equal columns.

However css is still evolving and there will be easier ways to manage this in the future but for now we either use these tricks or we go for a simpler method.

Right! That code was from your link here:

http://www.pmob.co.uk/search-this/absolute-columns3-hide.htm

For your example we don’t need the middle column because the background from the parent shows through and provides that column color. It provides the background to all three columns actually but because we are overlaying the left and right then all we see is the middle.

However if you wanted three separate columns colours with white gaps between then you would need to paint each column with the absolute column technique which would mean the middle column would be placed at left:xxpx so that it matches the content of that column.

In your example we only needed to place the first and last columns which we did with left:0 and then right:0. Of course in a fixed width layout we could have placed the right column with left:xxpx of course as we know where it should be.

Okay, that straighten things out for me!

Thanks,

TomTees

P.S. Why is something that is visually so simple, so difficult to do and understand on the web?! GEESH!!!

Hi Tom,

I’ll try to answer some of these for you while Paul is offline.

We make this selector (position: relative) to create a “containing block” from which all absolute positioned selectors will base their settings on, correct?
That’s correct, the absolute positioned faux divs (#one and #three) will set their coordinates from the page wrapper now instead of the viewport.

What is * html called again?

What is it that we are doing here again? (This wasn’t in your article but was somewhere else that I forgot.)
That is the “star html hack”, it targets IE6 and under. IE6 does not support min-max widths or heights but it has it’s own little quirk where it treats height as if it were min-height. It’s called the “Expanding Box” bug and it expand an element if it’s content exceeds the specified width/height.

In order to set a “z-index” this selector must be a “positioned” item, right?
That’s correct, only positioned elements are capable of taking on z-index stacking orders.

By setting the z-index=2 we are placing it on top of our later-to-follow colored absolute columns, right? (I think they are left blank making them have a z-index=0, right?)
That’s correct, the AP faux columns extend the full height of the wrapping div and they actually paint behind the header since their coordinates are top:0; and bottom:0;

Why do we set position: relative for the header?

If there was no background-color would we see our later-to-follow colored absolute columns?
RP was set on the header in order to set z-index as you answered above.

Yes, the faux column BG colors are painting behind the header.

/* LEFT COLUMN /
#col1 {
z-index: 2; /
NEW /
position: relative; /
Containing Block / / NEW /
float: left;
width: 150px;
min-height: 100px; /
If no content, prevent Floats from moving over to fill space. */
background-color: yellow;
}

Same questions as above about why we chose the z-index and position: relative here…

/* CENTER COLUMN /
#col2 {
z-index: 2; /
NEW /
position: relative; /
Containing Block / / NEW /
float: left;
width: 630px;
min-height: 100px; /
If no content, prevent Floats from moving over to fill space. */
background-color: #CCFFFF;
}

More of the same…

#col3 {
z-index: 2; /* NEW /
position: relative; /
Containing Block / / NEW */
float: right;
width: 150px;
background-color: #D685AD;
}

More of the same…
Those are the actual CONTENT divs, the only ones that really need the z-index are the left and right columns (#col1 and #col3). That is to stack them above the AP faux columns. Even though the faux columns do not have a z-value applied to them they have a higher stacking level since they are lower down in the source order. The left and right columns are getting z-index:2; to keep the text on top of the faux columns.

#footer {
clear: both; /* Keep below columns. /
width: 930px;
height: 40px; /
Matches negative margin on #wrapperMinusFooter. */
margin: 0 auto;
background-color: gray;
}

Apparently the clear: both works work the Floats above as it normally would, right? (i.e. our absolute columns won’t mess it up?)
That’s right, but with the footer sitting outside of the wrapper div it is clearing the floats anyways. As long as the wrapper is containing it’s floats which it is with the clearfix/IE8 rule in your question below.

/* OPERA FIX */
body:before {
    float: left;
    width: 0;
    height: 100%;
    margin-top: -32767px;        /* Negates effect of float. */
    content: "";
}

I have no clue what this says or is doing?! If you could take some time to explain it better, that would be fabulous!!
That is to fix an Opera min-height:100% bug, there is a thread running around here somewhere that explains it in detail.

Here it is -
Opera body:before float ? (sticky footer)

We were able to eliminate an extra wrapping div in previous versions of the sticky footer by using a negative top margin instead.

/* IE8 FIX INSTEAD OF USING DISPLAY TABLE. */
#wrapperMinusFooter:after {
    clear: both;
    display: block;
    height: 1%;
    content: " ";
}

I have no clue what this says or is doing?! If you could take some time to explain it better, that would be fabulous!!
That is killing two birds with one stone. It is fixing an IE8 min-height:100% bug with the height:1% rule. It forces IE8 to look to the :after block’s parent (wrapper div) and confirm it’s height. Since it is min-height:100% it is not a defined height and cannot be passed on to the :after block. It just tricks IE8 into getting min-height:100% correct.

It will also force the wrapper to contain any child floats.

/* CREATE BACKGROUND COLOR FOR COLUMNS */
#one{
    clear: both;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 150px;
    background: yellow;
}

Apparently the clear: both has the same purpose here as it does on my columns above with Float: Left/Right and position: relative ???
Actually the clear:both on that AP div is just to fix an IE bug.

I’ll take a break here where the bold red text begins and answer them in another post :slight_smile:

Okay Paul O’, you offered to help me out some more, so here come a whole bunch of questions regarding your solution above.

Attached is a screenshot of my finished (and working) example. In addition, I am attaching my code in case you need it for reference.

Questions are in BOLD below…

STYLESHEET: 05_ThreeCol_Fixed_Sticky_ColoredCols.css

html, body, h1, h2{
	margin: 0;
	padding: 0;
}

html, body {
	height: 100%;			/* Set a baseline for height. */
}

Okay so far…

/* PAGE CONTAINER */
#wrapperMinusFooter {
	width: 930px;					/* Width of Content. */
	min-height: 100%;			/* Based on height of <body>. */
	margin: 0 auto;				/* Center page. */
	margin-top: -40px;		/* Used to offset Footer height. */
	background-color: #CCFFFF;
	/* background:url(images/3colbackground.gif) repeat-y 0 0;	*/
	/* Create the illusion of 3 columns with one background image. */
	border: 0 1px solid #FFFFFF;
  position: relative;		/* Containing Block */	/* NEW */
}

We make this selector (position: relative) to create a “containing block” from which all absolute positioned selectors will base their settings on, correct?

* html #wrapperMinusFooter {		/* IE6 and under only. */
    height:100%;
}

What is * html called again?

What is it that we are doing here again? (This wasn’t in your article but was somewhere else that I forgot.)

/* HEADER */
#header {
	z-index: 2;	/* NEW */
	position: relative;	/* NEW */
	width: 100%;
	color: #FFFFFF;
	background-color: #000000;
	border-top: 40px solid #FF0000;		/* Offset negative margin of #wrapperMinusFooter. */
}

In order to set a “z-index” this selector must be a “positioned” item, right?

By setting the z-index=2 we are placing it on top of our later-to-follow colored absolute columns, right? (I think they are left blank making them have a z-index=0, right?)

Why do we set position: relative for the header?

If there was no background-color would we see our later-to-follow colored absolute columns?

/* NAVIGATION BAR */
#nav {
	background-color: orange;
}

Nothing special here!

/* LEFT COLUMN */
#col1 {
	z-index: 2;	/* NEW */
	position: relative;		/* Containing Block */	/* NEW */
	float: left;
	width: 150px;
	min-height: 100px;		/* If no content, prevent Floats from moving over to fill space. */
	background-color: yellow;
}

Same questions as above about why we chose the z-index and position: relative here…

/* CENTER COLUMN */
#col2 {
	z-index: 2;	/* NEW */
	position: relative;		/* Containing Block */	/* NEW */
	float: left;
	width: 630px;
	min-height: 100px;		/* If no content, prevent Floats from moving over to fill space. */
	background-color: #CCFFFF;
}

More of the same…

/* RIGHT COLUMN */
#col3 {
	z-index: 2;	/* NEW */
	position: relative;		/* Containing Block */	/* NEW */
	float: right;
	width: 150px;
	background-color: #D685AD;
}

More of the same…

/* FOOTER */
#footer {
	clear: both;			/* Keep below columns. */
	width: 930px;
	height: 40px;			/* Matches negative margin on #wrapperMinusFooter. */
	margin: 0 auto;
	background-color: gray;
}

Apparently the clear: both works work the Floats above as it normally would, right? (i.e. our absolute columns won’t mess it up?)

/* OPERA FIX */
body:before {
    float: left;
    width: 0;
    height: 100%;
    margin-top: -32767px;		/* Negates effect of float. */
    content: "";
}

I have no clue what this says or is doing?! If you could take some time to explain it better, that would be fabulous!!

h1, h2, p {
    padding: 0 10px;		/* ?????? */
}

Does this have any hidden meaning/purpose or are you just adding some padding?! :-/

/* IE8 FIX INSTEAD OF USING DISPLAY TABLE. */
#wrapperMinusFooter:after {
    clear: both;
    display: block;
    height: 1%;
    content: " ";
}

I have no clue what this says or is doing?! If you could take some time to explain it better, that would be fabulous!!

/* CREATE BACKGROUND COLOR FOR COLUMNS */
#one{
	clear: both;
	position: absolute;
	top: 0;
	bottom: 0;
	left: 0;
	width: 150px;
	background: yellow;
}

Apparently the clear: both has the same purpose here as it does on my columns above with Float: Left/Right and position: relative ???

*** Okay, here is where I am particularly confused… ***

Your article mentions that we “attach” the absolute column to the bottom of our “containing block” (i.e. relative div) but here I see you using:

position: absolute;
top: 0;
bottom: 0;

You specifically said…

This technique is based on the fact that if you place an absolute element inside a relative container and set the absolute element to height:100% (or top:0 and bottom:0) it will expand in tune with the parent container…

…but I don’t understand what this does and it seems contradictory when you mention height:100% (or top:0 and bottom:0)

You then go on to say later in your article…

Instead we are going to place the absolute element at the bottom of the relative parent and give it a height of 1000em. Now instead of the absolute element going down the page it starts at the bottom of our columns and travels up the page and out the top of the browser window.

…but I don’t see that in the block of code above or anywhere?!

(In my opinion) This needs to be re-written and explained better!

#three{
	clear: both;
	position: absolute;
	top: 0;
	bottom: 0;
	right: 0;
	width: 150px;
	background: #D685AD;
}

More of the same, however, why are we NOT doing this for Column #2???

How is it that Column #2 expands the full height of the browser window when it doesn’t have its own absolute column to do a background color?!

/* IE6 FIX */
* html #one,
* html #three{
		height: 9999em;
		top: auto;
}

Maybe this has something to do with above, but if you could explain it in detail it would help me to know what purpose it serves and what it actually does?!

WHEW!!! You made it!!

Sorry for all of the questions, but this is actually trickier than it initially looks, and I am seriously about REALLY LEARNING this stuff, so your detailed responses are greatly appreciated!!!

Sincerely,

TomTees

Yeah yeah, we are well aware of your opinions around here. They are kinda like your description of fixed width sites. All I did was say If it is a fixed width site” and here you come spouting off again. I hate to break it to you, but your hatred for fixed width sites is not enough to stop people from using them. Get over it already!

And how would I create one of those if I don’t have Photoshop?

Anything other than that requires empty divs for AP faux columns (extra markup & css).

Those are really only needed when it is a fluid width site.

I looked at the link and at the code, but th code is hard to follow…

1.) Why is there an extra “Outer” div?

2.) What does this do?

<div class="clearer"></div>

3.) Should the Footer be outside of the Wrapper if you want a “Sticky Footer”?

4.) Why does “Wrapper” have a z-index of 5 (putting it on top)?

5.) What does this do?

.col{
	width:200px;
	position:absolute;
	z-index:0;
	left:10px;
	bottom:0;
	border:1px solid #000;
	border-top:none;
}

6.) I’m not following this code either…

.one{background:red;}
.two{background:#FF6600;left:222px;width:334px;}
.three{background:#CC3399;left:568px;}

Seems like an awful lot of work to do something that should be so simple?! :-/

TomTees

… and since fixed width sites are half-assed crap that are usually more annoyance than useful…

Hi Rayzur. In the times I used this method, I never had to link to anchors in the containing block. It was most of the time for layout purpose so that’s why I probably never had problems :slight_smile: But thank you for the tip and link on this.

Hi Paul O’B, like I said, I was never in the situation where I had those “In page links”, at least not in a design as suggested by me! So what would you suggest if such a situation might occur? A background image?

There are different ways to have equal columns. One you mentioned yourself already. But to stay as close as possible to the layout you have so far, without to many adjustments, you you could do the following. Give the columns you would like to match the highest column (in your case that would be col1 and col3) a very large padding-bottom and an equal negative margin-bottom and set overflow: hidden; for the wrapper. The only thing you have to adjust is take the footer out of the wrapper. I.e.


html, body, h1, h2, p, div {
	margin: 0;
	padding: 0;
}



body {
	width: 100%;
	line-height: 1;
	font: 100%/130% Arial, Helvetica, sans-serif; 	
}

#wrapper {
	width: 930px;
	margin: 0 auto;
	overflow: hidden;
	background-color: #E0E0EB;
	border: 1px solid #FFFFFF;
}

/* HEADER */
#header {
	width: 100%;
	color: white;
	background-color: black;
}

/* NAVIGATION */
#nav {
	background-color: orange;
}

/* LEFT COLUMN */
#col1 {
	width: 150px;
	margin-bottom: -1000px;
	padding-bottom: 1000px;
	float: left;

	background-color: yellow;
}

/* CENTER COLUMN */
#col2 {
	width: 630px;
	float: left;
	background-color: #CCFFFF;
}

/* RIGHT COLUMN */
#col3 {
	width: 150px;
	margin-bottom: -1000px;
	padding-bottom: 1000px;
	float: left;
	background-color: #D685AD;
}
/* FOOTER */
#footer {
	width: 930px;
	margin: 0 auto;
	clear: both;
	background-color: gray;
}

<div id="wrapper">

    <div id="header">
    <h1>HEADER</h1>
    <div id="nav">NAVIGATION</div>
    </div>

<div>Your text here</div>

<div id="col1">COL1</div>

<div id="col2">
<h2>COL2</h2>
</div>

<div id="col3">COL3</div>

</div>

<div id="footer">FOOTER</div>