homepage Welcome to WebmasterWorld Guest from 54.211.231.221
register, free tools, login, search, subscribe, help, library, announcements, recent posts, open posts,
Pubcon Website
Visit PubCon.com
Home / Forums Index / Code, Content, and Presentation / CSS
Forum Library, Charter, Moderators: DrDoc

CSS Forum

This 42 message thread spans 2 pages: 42 ( [1] 2 > >     
CSS example: 100% height, footer stuck on bottom
swa66




msg:4015933
 10:44 pm on Oct 29, 2009 (gmt 0)

A step-by-step example of how to build your design.

It's not just the end result that I aim for, I aim probably more at showing the thought process of how to build your design without tearing out the last few hairs you've left :)

No IE

Yes, that's the start: ditch the browser of choice of the majority of your users. It's critical to do this is you value your sanity.

Chose any other browser: FF, Safari, Opera, ... I'll use Firefox for it has plug-ins like the web developer toolbar and firebug. But the others will work too as long as it's not "that" browser from Microsoft.

Start

I'm using a template for the html to start from.
Make it as strict as you can cause it will increase the number of errors you get from a code validation and make your code a lot better as a result.

I usually start from this in these guides:

<!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" xml:lang="en">
<head>
<title>Test</title>
<style type="text/css">
* {
padding: 0;
margin: 0;
}
</style>
</head>
<body>
<p>Hello World!</p>
</body>
</html>

The main thing I'd do different in a real life case is that I'd make the CSS a <link>. But for simpler cutting and pasting in this tutorial this will do.

HTML

Yes: make the html first.

<!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" xml:lang="en">
<head>
<title>Test</title>
<style type="text/css">
* {
padding: 0;
margin: 0;
}
</style>
</head>
<body>
<div class="header">
<a href="#"><img src="1.jpg" alt="logo" /></a>
<h1>title</h1>
</div>
<div class="middle">
<h2>heading</h2>
<p>Lorem ipsum ...</p>
<p>Add more content to make sure you can scroll as you need.</p>
</div>
<div class="footer">
<p>Footer text goes here</p>
</div>
</body>
</html>

Now does that validate ?

Yep it does!

Does it make sense without CSS ?

It does!

HTML done

I'll consider the HTML finished now. All the rest will have to be done in the CSS.

The 100% height framework

First let's center our body and give it a different color from the background

html {
background-color: #ccc;
}
body {
background-color: white;
width: 770px;
margin: 0 auto;
}

Why does this center it ?
Well the block element <body> is given a width and told to calculate it's left and right margin itself.

Next let's stretch it vertically to be at least the height of the viewport

html {
height: 100%;
}
body {
min-height: 100%;
}

The 100% height trick is all about: the 100% references the height of the direct parent, provided the parent has an explicitly set height different from "auto".
The exception is the root element that has the height of the viewport.

min-height instead of height is what makes it at least as high as the content (and not cut our body off where the viewport stopped).

Try it with different sizes of viewport and different sized content a bit.

Now what would happen if we were to add a border or padding or vertical margins to <body> ? Try it !
So remember we need to avoid adding anything that's going to add to the height of the body. The 100% sets the height of the content, not the overall height.

So we'll need to add the border in a different fashion then.

Stick the footer to the bottom

By stick to the bottom in this case I meant stick it under the content if the content is longer than the viewport, and stick it at the bottom if the content isn't long enough to fill the viewport.

You can also stick it always at the bottom of the viewport: you use position fixed instead of position: absolute in that case.

Absolute positioning:

body {
position: relative;
}
.footer {
position: absolute;
background-color: yellow;
bottom: 0;
left:0;
}

Nice, but the footer is lacking the width it needs.
I'm sure after the talk about 100% height most would wonder about 100% width:

.footer {
width: 100%;
}

And it will work to get the footer the width of it's parent (the body).
But there is a bit of an issue if we're not careful: try adding padding on the footer and it'll grow to be too large horizontally to fit anymore.

There are ways to deal with that (and we'll show them where we deal with IE6 much later).
The reason the width get's too large is cause we derive the overall width from the width of the content (which we can set), and then the padding is added around that.
But when we use absolute positioning, setting the overall with is more than easy enough:


.footer {
position: absolute;
background-color: yellow;
bottom: 0;
left:0;
right:0;
}

Yes, we set left and right and the width will adapt to what's needed.
We can now set the padding as we like. Try it!

Layout the header

I need to fix the header (mostly cause my test image is way too large), but also to show some neat tricks.

Let's remove that ugly blue border:

a img {
border:none;
}

This will remove borders on all images that are inside a link.

Let's also position and size the header:

.header {
background-color: orange;
position: relative;
min-height: 110px;
}
.header a img {
width: 150px;
height: 100px;
position: absolute;
top: 5px;
left: 5px;
}
.header h1 {
padding: 20px 0 0 160px;
}

notice that I didn't have to control the width of the header: it's using the width of it's parent.

You can lay it out as you like, it's just one way, nothing more.

Fix the overlap

If your content is larger than the viewport, the footer is sitting on top of the content itself. This needs fixing.
But the footer is absolutely positioned so it has no influence over the in-flow elements.
The solution is to make sure the content has whitespace that sticks out below the footer:


.middle {
padding-bottom: 2em;
}

The 2em is a bit much, we can adapt that later (or the footer might use some padding and might not even be enough.

Now why does this work?
The middle div isn't stretched ?
Nope but it's got a padding sticking out beyond it's content that leaves room for the footer to overlap should it want to do that.

To visually see it at work: add a background color on .middle and resize your browser window.

Adding some padding

Where to add padding is tricky:

  • you can't add top or bottom things on the body or it breaks
  • you can't add left or right things to the footer or it breaks (if we choose to set the width instead of setting the left and right position)
  • we can't add left or right padding on the body or it disconnects the header and footer from the sides (and that's what we'll need for the border later)

So what works ?

.middle {
padding: 0 5px 2em 5px;
}
.footer p {
padding: 5px;
font-size: 80%;
}

I've collapsed the 2em bottom padding into the shorthand padding on the .middle

The .footer p can have padding, its width isn't set.

I already took care of the header above.

Adding a border

A border is just as tricky as the padding above, but we can add left and right borders on the body and we can add a top border on the header and a bottom border on the footer:

body {
border-left: 1px solid #888;
border-right: 2px solid black;
}
.footer {
border-bottom: 2px solid black;
}
.header {
border-top: 1px solid #888;
}

Colors and thickness are easy enough to adjust.

Removing the background colors showing us where the elements are and putting it all together we end up with:

<!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" xml:lang="en">
<head>
<title>Test</title>
<style type="text/css">
* {
padding: 0;
margin: 0;
}
html {
background-color: #ccc;
height: 100%;
}
body {
background-color: white;
width: 770px;
margin: 0 auto;
min-height: 100%;
position: relative;
border-left: 1px solid #888;
border-right: 2px solid black;
}
.footer {
position: absolute;
bottom: 0;
left:0;
right:0;
border-bottom: 2px solid black;
}
a img {
border:none;
}
.header {
position: relative;
min-height: 110px;
border-top: 1px solid #888;
}
.header a img {
width: 150px;
height: 100px;
position: absolute;
top: 5px;
left: 5px;
}
.header h1 {
padding: 20px 0 0 160px;
}
.middle {
padding: 0 5px 2em 5px;
}
.footer p {
padding: 5px;
font-size: 80%;
}
</style>
</head>
<body>
<div class="header">
<a href="#"><img src="1.jpg" alt="logo" /></a>
<h1>title</h1>
</div>
<div class="middle">
<h2>heading</h2>
<p>Lorem ipsum ...</p>
<p>Add more content to make sure you can scroll as you need.</p>
</div>
<div class="footer">
<p>Footer text goes here</p>
</div>
</body>
</html>

Test

Let's test it first in the other standards compliant browsers:

Seems to work fine in FF, Opera, Safari and Chrome.

So this is another milestone like the one where we declared the html done. The CSS is now done.

I can hear you think: but you didn't even test it in IE ! How can it be done ?

Yes it's done. We'll add conditional comments to work around issues that IE has.
The reason for not adding anything back into the main CSS is to keep it all simple and possible to wrap our head around. And mainly not to have to care why IE does what it does.

Work around IE bugs

To work around the bugs in IE we need to test it first. Easiest is IE8 in most cases, most difficult is IE6 in virtually all cases.

IE8: does OK as expected
IE7: does OK as well (I had hoped to have something to fix to be honest)
IE6: there's no chance it'll do it properly

IE6 doesn't understand min-height, but its height is broken enough to be able to be a good substitute.

And the setting of both sides on the footer isn't working either (expected)

Adding the conditional comment to fix it:

<!--[if IE 6]>
<style type="text/css">
body {
height: 100%;
}
.header {
height: 110px;
}
.footer {
width: 100%;
}
</style>
<![endif]-->

This yields:


<!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" xml:lang="en">
<head>
<title>Test</title>
<style type="text/css">
* {
padding: 0;
margin: 0;
}
html {
background-color: #ccc;
height: 100%;
}
body {
background-color: white;
width: 770px;
margin: 0 auto;
min-height: 100%;
position: relative;
border-left: 1px solid #888;
border-right: 2px solid black;
}
.footer {
position: absolute;
bottom: 0;
left:0;
right:0;
border-bottom: 2px solid black;
}
a img {
border:none;
}
.header {
position: relative;
min-height: 110px;
border-top: 1px solid #666;
}
.header a img {
width: 150px;
height: 100px;
position: absolute;
top: 5px;
left: 5px;
}
.header h1 {
padding: 20px 0 0 160px;
}
.middle {
padding: 0 5px 2em 5px;
}
.footer p {
padding: 5px;
font-size: 80%;
}
</style>
<!--[if IE 6]>
<style type="text/css">
body {
height: 100%;
}
.header {
height: 110px;
}
.footer {
width: 100%;
}
</style>
<![endif]-->
</head>
<body>
<div class="header">
<a href="#"><img src="1.jpg" alt="logo" /></a>
<h1>title</h1>
</div>
<div class="middle">
<h2>heading</h2>
<p>Lorem ipsum ...</p>
<p>Add more content to make sure you can scroll as you need.</p>
</div>
<div class="footer">
<p>Footer text goes here</p>
</div>
</body>
</html>

[edit]Edit: spelling, grammar and layout[/edit]

[edited by: swa66 at 12:13 pm (utc) on Nov. 11, 2009]

 

swa66




msg:4015939
 10:50 pm on Oct 29, 2009 (gmt 0)

Need to clarify a few bugs in IE6 that I did not bother trying to work around:
- it has it's own version of what feels like a rounding error where the positioning often is a pixel off. I don't know of a fix and it depends on the viewport size if you see it or not.
- if the window is too narrow to fit the page, the bottom scrollbar make the viewport less high, but IE6 forgets that and doesn't make the body the right height, pushing the footer halfway under the scrollbar.

simonuk




msg:4019084
 4:41 pm on Nov 4, 2009 (gmt 0)

Very nice post :-)

vincevincevince




msg:4022982
 8:13 am on Nov 11, 2009 (gmt 0)

The setting left & right bit is a great tip... for some reason that never occurred to me

Rumbas




msg:4023054
 10:54 am on Nov 11, 2009 (gmt 0)

Whoa! Nice post and very good for us errmm css clowns :)

StoutFiles




msg:4023116
 12:55 pm on Nov 11, 2009 (gmt 0)

I still say you should design in both Firefox AND IE simultaneously. How will you know exactly what in the CSS isn't working properly? Make a change then check them both.

In a scientific test you only want to introduce one variable to the equation to see the effects on the system. Adding more than one and you'll have no idea which variable did what. That holds true with website design as well.

swa66




msg:4023145
 1:56 pm on Nov 11, 2009 (gmt 0)

design in both Firefox AND IE simultaneously

One problem is that you'll have to deal with _all_ the bugs of every version of IE, even those that your final design does not trigger.

The second problem is that IE is going to hold you back in what you can do, preventing you from doing anything beyond the most basic CSS. Instead of allowing you to use all the spectrum of what's possible and then give you the option to find in the end something that looks OK enough for these legacy versions.

Moreover IE constantly sets you on the wrong foot, slowing you down significantly.

Mixing in workarounds for legacy IE versions in the main CSS is also counterproductive in the long term as it encourages browser crafters to emulate the bugs in old versions IE.

The worst of it all: dealing with all the IE bugs just drives you nuts.

kapow




msg:4023165
 2:41 pm on Nov 11, 2009 (gmt 0)

No IE. Yes, that's the start: ditch the browser of choice of the majority of your users. It's critical to do this if you value your sanity.

Here on planet Earth we have to make a living, so we put up with the insanity and work with the overwhelmingly most popular browser.

[edited by: kapow at 2:43 pm (utc) on Nov. 11, 2009]

GryphonLeon




msg:4023168
 2:42 pm on Nov 11, 2009 (gmt 0)

Great post! I had to use a similar setup for several sites and the first time I had to create this, IE drove me crazy.

Just one small note I want to add:

In IE8, if you resize your viewport to say half the height of your screen and then refresh the page, it looks good. But when you then drag the bottom of your window down so the viewport gets higher, the footer doesn't stick to the bottom. In order to fix this, you have to add height: 100%; to the body tag.

abidshahzad4u




msg:4023175
 2:49 pm on Nov 11, 2009 (gmt 0)

Great work!

chicagohh




msg:4023214
 4:15 pm on Nov 11, 2009 (gmt 0)

Yes, that's the start: ditch the browser of choice of the majority of your users.

That's where I stopped reading. Clients don't care about technical or political issues with browsers. They hire people to simply make it work. Most of the client stats that I look at still show 10% to 18% of all visitors use IE6.

Fotiman




msg:4023217
 4:20 pm on Nov 11, 2009 (gmt 0)

Nice! Now how about an HTML5 example using <header> and <footer>. :)

Najim




msg:4023231
 4:44 pm on Nov 11, 2009 (gmt 0)

great piece of work for fixing browser issues i really like it :)

JohnCanyon




msg:4023245
 5:18 pm on Nov 11, 2009 (gmt 0)


Clients don't care about technical or political issues with browsers.

Join the movement.. educate your clients! Ditch "that" browser.

You should continue reading his post however, as there are "workarounds" to make this compliant with "that" browser.

=P

dailypress




msg:4023263
 5:46 pm on Nov 11, 2009 (gmt 0)

I love WW.

swa66




msg:4023296
 7:08 pm on Nov 11, 2009 (gmt 0)

That's where I stopped reading.

That's a pity: because it does support it, it's just that during the design you should not use it till the very end. That's if you value time and sanity.

Judah_Ben




msg:4023335
 8:21 pm on Nov 11, 2009 (gmt 0)

Nice post.

However, after completing the development, I would definitely consider going through and testing/developing for IE 6. An alarming percentage of users still use IE 6, and you don't want to exclude them from interacting with your website.

I don't like IE 6 at all, but some of our largest clients use only IE 6. While it costs some sanity, being able to deliver a quality product speaks for itself.

Often times larger organizations resist updating their browser versions. This is because it can be a potential IT nightmare. Some of our clients are behind massive firewalls and are not able to even download basic flash updates.

The three industries I've see still using IE 6 are:
Construction,
Law (firms etc...),
Health Insurers

Granted not everyone in those industries is using IE 6, there are many that do.

On that note, here's an IE 6 hack that we use for min-height. I insert it into a separate style sheet that is placed between the <!--[if IE 6]> <![endif]--> .

.header {
min-height:110px;
height:auto !important;
height:110px;
}

Thanks,
-JB

Fotiman




msg:4023384
 9:34 pm on Nov 11, 2009 (gmt 0)

@Judah_Ben, I think you misread the post. swa66 did not say ignore IE6 altogether, but rather during the development stage use a standards compliant browser (like Firefox) and then add IE6 fixes when your main development is complete. swa66 also included a fix for min-height in IE6. Note, your example includes extraneous styles. You are including that stylesheet for IE6 only, which means that there's no need to include a min-height rule (IE6 will ignore it). Likewise, there is no need to define the height using !important and then defining height again (that is a hack that you might use INSTEAD OF using conditional comments). Again, since only IE6 will be looking at that stylesheet, you can simply define a height rule... as swa66 did in the original example.

mack




msg:4023422
 10:38 pm on Nov 11, 2009 (gmt 0)

Swa66,
A simply awesome post, lots of detail, yet simple enough to understand. I appreciate you taking the time to share this with us.

Mack.

swa66




msg:4023481
 12:35 am on Nov 12, 2009 (gmt 0)

@GryphonLeon

I've tried to reproduce the problem you describe:
In IE8, if you resize your viewport to say half the height of your screen and then refresh the page, it looks good. But when you then drag the bottom of your window down so the viewport gets higher, the footer doesn't stick to the bottom.

But, I cannot get it to do that (and I tried as tall as I can make it on my 1920x1200px screen).

Did you use the last code segment in the original post?

In order to fix this, you have to add height: 100%; to the body tag.

The min-height on the body takes care of it in this example. It changes if you use an additional wrapper, but in this case the min-height seems to work just fine in IE8 (even if you toggle it back to IE7). It's only IE6 that doesn't know what min-height is.

GryphonLeon




msg:4023639
 8:41 am on Nov 12, 2009 (gmt 0)

@swa66

Yes, I used the last code segment in your original post. I'm able to reproduce the problem on another pc (and the 100% height fixes it again).

After you resize the viewport to half the height of your screen, make sure you refresh the page so the vertical scrollbar disappears. Then, drag the bottom of the IE window down so the viewport gets higher. My guess is that you didn't refresh the page?

scotland




msg:4023670
 10:14 am on Nov 12, 2009 (gmt 0)

swa66

Nice post and I am about to show my ignorance of css

why use .header etc rather than #header

swa66




msg:4023710
 12:46 pm on Nov 12, 2009 (gmt 0)

@GryphonLeon

I tried refreshing on large, small viewports, both vertically and horizontally both with and without scrollbars: I've not seen the effect you describe once.
I tried it with IE8 in IE8 and in IE7 mode: made no difference whatsoever.

I run a rather virgin IE8 on XPSP3 in a virtual machine (parallels).

Anybody else that can trigger this with IE8 and the code provided ?

swa66




msg:4023712
 12:50 pm on Nov 12, 2009 (gmt 0)

why use .header etc rather than #header

elements in your html with class="header" can be selected in CSS with ".header"
the element in your html with id="header" can be selected in CSS with "#header"

So the question might be when to use a class or an id.
An id is only allowed once in a html document, a class can occur multiple times.
In this case an id would have done just fine, it can even be argued to be better.

I didn't stop to think about it (the goal was different), if I did I might actually have gone for an id in hindsight.

scotland




msg:4023734
 1:18 pm on Nov 12, 2009 (gmt 0)

swa66

Thanks for that - I have been reading books on CSS and using CSS for a while and it was only last week that I eventually started to use class as well as id. Is this a common mistake when using CSS, to not understand how and when to use Class?

(not in your example, in my own use of ID and not using Class)

Fotiman




msg:4023764
 2:35 pm on Nov 12, 2009 (gmt 0)


So the question might be when to use a class or an id.
An id is only allowed once in a html document, a class can occur multiple times.
In this case an id would have done just fine, it can even be argued to be better.

I didn't stop to think about it (the goal was different), if I did I might actually have gone for an id in hindsight.


And note, with HTML5 the approach will be different still, using the new <header> and <footer> semantic elements instead of classes or ids. :)

Fotiman




msg:4023772
 2:42 pm on Nov 12, 2009 (gmt 0)

@scotland, I think of it like this. If the thing I am styling is a "type" of an object, and I think it could theoretically be reused multiple times on a page, then apply styles using a class. If, however, the thing I am styling is an "instance" of an object, and I know it explicitly refers to an element that will only ever appear once on the page, then use an id. Often times this means that the core structure of the page uses ids, and those contain various classed elements. For example:


<body id="home">
<div id="header">
...
</div>
<div id="content">
<div class="article">...</div>
<div class="article">...</div>
<div class="article">...</div>
</div>
<div id="footer">
...
</div>
</div>

The important distinction is that id's must be unique and only appear once on a page. If you think you're styling a more general "class" of elements, then use class.

GryphonLeon




msg:4023898
 5:10 pm on Nov 12, 2009 (gmt 0)

@swa66

Both machines I tested this on are Vista PCs with IE8 (IE8 mode). Unfortunately I don't have access to a WinXP/IE8 combination. I could post a screenshot if you'd like.

swa66




msg:4025105
 1:14 am on Nov 15, 2009 (gmt 0)

I've started a new topic to explore the IE8 oddity further, hopefully with a bigger audience participating in it:
[webmasterworld.com ], let's see if we can figure out how to reproduce what GryphonLeon has.

[edited by: swa66 at 11:38 am (utc) on Nov. 15, 2009]

GryphonLeon




msg:4025204
 9:53 am on Nov 15, 2009 (gmt 0)

Thanks swa, it would be great to see the outcome of this! Small note, the link in your last post isn't working, there's a comma in the URL :)

This 42 message thread spans 2 pages: 42 ( [1] 2 > >
Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / CSS
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About
© Webmaster World 1996-2014 all rights reserved