tags:

views:

500

answers:

13

If you only had to worry about Firefox and Webkit browsers, what CSS would you use to make the footer in the following HTML not rise above the bottom or the screen (and go lower if the body content pushed it)? Note: I don't want to add any of markup to the page.

<html>
    <body>
        <header>...</header>
        <article>...</article>
        <aside>...</aside>
        <footer>...</footer>
    </body>
</html>

Here is some copy paste html. How do I need to modify the css to make it work?

<!DOCTYPE html>
<html>
    <head>
        <style type="text/css">
            * {
                margin: 0;
                padding: 0;
            }

            ul {
                list-style: none;
            }

            p {
                margin-bottom: 10px;
            }

            article {
                display: inline-block;
                height: auto;
                width: 69%;
            }

            aside {
                display: inline-block;
                height: auto;
                width: 30%;
            }

            footer {
                height: 30px;
            }
        </style>
    </head>
    <body> 
        <header>
            <h1>Lorem Ipsum</h1>
        </header> 
        <article>
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam eu viverra mauris. Fusce at erat risus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed tincidunt orci eget justo ornare vel iaculis mauris commodo. Ut id leo ipsum. Donec nunc est, convallis sit amet vehicula eget, laoreet id odio. Proin vitae purus magna. Maecenas lorem lacus, convallis ac imperdiet in, ullamcorper sed leo. Maecenas suscipit justo at arcu placerat eu ultricies orci placerat. Etiam vel erat in metus porttitor tristique vel ultricies ante. Aliquam sed porttitor nunc. Sed venenatis, sapien lacinia laoreet facilisis, lectus turpis iaculis leo, nec rhoncus tellus erat bibendum felis. Integer cursus malesuada sem id vehicula. Duis venenatis pellentesque nisi ut vulputate. Nunc elit sapien, pulvinar blandit suscipit ut, imperdiet ut neque. Cras odio dolor, commodo vitae malesuada sed, tempus sed neque.</p>
            <p>Sed nec ornare libero. Vivamus ut risus at ligula dignissim lobortis. Pellentesque dignissim iaculis fringilla. Quisque porta sagittis massa eu euismod. Vivamus nunc lectus, iaculis vitae tincidunt et, placerat at risus. Nunc elementum massa at ligula blandit quis volutpat nulla malesuada. Nunc felis massa, placerat at vehicula non, gravida a nibh. Fusce adipiscing magna et nisl aliquet vehicula posuere tortor tempor. Aliquam erat volutpat. Duis eu enim sit amet lacus hendrerit elementum vitae a purus.</p>
            <p>Phasellus porttitor congue tellus, eget rhoncus eros consequat a. Donec faucibus lorem at sapien aliquam tempus. Sed sed vulputate magna. Proin eros felis, eleifend vitae posuere vel, dictum ut purus. Pellentesque id felis sit amet neque consectetur porta. Donec non tellus augue, a sollicitudin libero. Nullam blandit hendrerit lacus. Quisque ac libero sapien. Etiam luctus tellus non sapien fringilla ultrices. Aliquam ut erat ut sapien mattis rhoncus nec eu enim. Aenean elementum dui in ligula fermentum nec egestas dui luctus. Praesent sed purus id tellus lacinia aliquam. Donec luctus, metus ut pulvinar bibendum, sapien dui aliquet est, volutpat cursus enim massa non sapien. Quisque mollis nisl a arcu ullamcorper porta. Nunc dapibus pellentesque dui in varius. Donec et eros ut lacus commodo vehicula.</p>
        </article> 
        <aside>
            <ul>
                <li>One</li>
                <li>Two</li>
                <li>Three</li>
                <li>Four</li>
                <li>Five</li>
            </ul>
        </aside> 
        <footer>
            <span>Made by me.</span>
        </footer> 
    </body> 
</html> 
A: 

CSS:

* {
margin: 0;
}
html, body {
height: 100%;
}
.wrapper {
min-height: 100%;
height: auto !important;
height: 100%;
margin: 0 auto -4em;
}
.footer, .push {
height: 4em;
}

HTML:

<html>
    <head>
        <link rel="stylesheet" href="layout.css" ... />
    </head>
    <body>
        <div class="wrapper">
            <div class="header"></div>
            <div class="article"></div>
            <div class="aside"></div>
            <div class="push"></div>
        </div>
        <div class="footer">
            <p>Copyright (c) 2008</p>
        </div>
    </body>
</html>
bpeterson76
That is similar to what I use right now, I just don't like having to put wrappers and pushes into the markup. I was wondering if there was a more pure way to accomplish this.
Jason Christa
Yeah, it's not ideal, but given the limitation that browsers such as IE force us UI guys into, there's not a ton of options out there. Here's another option that removes the "push" div: http://www.cssstickyfooter.com/html-code.html. Take it one step further with the outstanding 960 grid system here: http://signalkraft.com/sticky-footer-in-960-grid-system
bpeterson76
Oh yeah, I am almost sure this can't be done in IE, which is why I limited it to just Firefox and Webkit browsers.
Jason Christa
A: 

you could try something simple like auto heights on the article and aside, this would in theory push the footer down to where the content finishes and the footer would start after that allowing it to be dynamic, and automatic.

The Html

<html> 
    <body> 
        <header>...</header> 
        <article>...</article> 
        <aside>...</aside> 
        <footer>...</footer> 
    </body> 
</html> 

The CSS

.artice {height:auto;}
.aside {height:auto;} 
.footer{ 
height: YOU CHOOSE; 
} 

Note: for styling purposes you might not want the footer to be exactly when the content ends, so you might want to add margin-top:10px; to the footer css, just in case you are a perfectionist.

Ryan Murphy
Except if your content was short, the footer would be in the middle of the page.
Jason Christa
Not true. height:auto deals with that.
Ryan Murphy
A: 

I think you're talking about the margin of 10-15 pixels below the footer. Try adding this code to your CSS;

body { margin-bottom:0px; }

The body has a default margin of 10-15 pixels so in order to remove it to flush your design to the top or bottom you have to tell the body to have a margin of zero.

Hope that helps.

s_broderick
A: 

* { display:block; }

You are going to have to change the display to inline in your wrapper after that though.

Mowgli
+1  A: 

Here is the link, http://files.nextscreen.com/test.html . The code in the head section is below.

I think I figured this out:

<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"&gt;&lt;/script&gt;
<![endif]--> 
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/3.1.1/build/cssreset/reset-min.css"&gt;
<style type="text/css">
    html {
        background-color: orange;
        height: 100%;
    }

    body {
        background-color: yellow;
        height: auto;
        min-height: 100%;
        position: relative;
    }

    ul {
        list-style: none;
    }

    p {
        margin-bottom: 10px;
    }

    header {
        background-color: red;
        display: block;
    }

    article {
        background-color: blue;
        display: inline-block;
        margin-bottom: 30px;
        vertical-align: top;
        width: 70%;
    }

    aside {
        background-color: green;
        display: inline-block;
        margin-bottom: 30px;
        vertical-align: top;
        width: 30%;
    }

    footer {
        background-color: pink;
        bottom: 0;
        height: 30px;
        left: 0;
        position: absolute;
        width: 100%;
    }
</style>
Jason Christa
How many browsers did you test that in? Does absolute on `footer` not cause issues? It would help seeing your layout visually.
meder
I used this style with my copy paste html in my question. It worked with there were only a few paragraphs and when there were lots of paragraphs spanning several screens. Have you tried it in Chrome and Firefox?
Jason Christa
Does not work in IE8 for me.
JochenJung
It doesn't work in IE8 because IE won't style elements it does not know, ie: header, article, aside, footer. If they were all divs this would work in IE8.
Jason Christa
@Jason - see my answer for targeting IE.
meder
+1 as I promised in the comment on my solution. Look's like we both ended up with something that worked per your requirements.
Scott
Of course, mine does have the equal height columns :-)
Scott
One nice thing about yours is that IE7 works, and if you change your `body` tag definition to trick IE6 to give it `min-height` by doing the `height: auto !important` followed by the `height: 100%` then your solution works in IE6 also.
Scott
@Scott: Equal height columns is a separate issue but you can put the article and aside in a div and do div{dispay:table} article,aside{dispay: table-cell}. To make it work everywhere you do div{overflow:hidden} article,aside{padding: 30000px; margin: -30000px}.
Jason Christa
I agree, I also noticed that mine are only equal height with short content, not with long content... oh well :-)
Scott
A: 

First of all, no matter what you do, you'll need a wrapper div for the entire page. I usually call it #page_container or something. If you think about it, having a div container for the whole page doesn't defeat the essence of css style sheets. On the other hand, if you had a bunch of wrappers scattered around the html page, it could potentially get pretty messy with all that extra markup. So, I always use a page_container on my layouts, even if I don't put any css styling on it, I always have one. Basically, it will just act like a body tag, only allow you to style it.

With that said, there are a couple solutions if your layout was refined to:

<html>
...
<body>
<div id='page_container'>
    <div id='header'></div>
    <div id='contents'></div>
    <div id='footer'></div>
</div>
</body>
</html>

Only Firefox you say? Did I hear that right? I don't think I've ever heard anyone say that before. In that case, its fairly easy. The easiest solution would be:

<html>
<head>
    <title>Test page</title>
        <style>
            body{
                background-color:green;
                margin:0px;
            }
            #page_container{
                width:700px;
                margin-left:auto;
                margin-right:auto;
                display:table;
                height:100%;
            }
            #header{
                background-color:red;
                text-align:center;
                font-size:25px;
                font-weight:600;
                height:75px;
                display:table-row;
            }
            #contents{
                background-color:yellow;
                display:table-row;
            }
            #footer{
                background-color:blue;
                height:25px;
                display:table-row;
            }   
    </style>
</head>
<body>
    <div id='page_container'>
        <div id='header'>Title of your page</div>
        <div id='contents'>
            Foo bar baz<br/>
            Foo bar baz<br/>
            Foo bar baz<br/>
            Foo bar baz<br/>
            Foo bar baz<br/>
            Foo bar baz<br/>
        </div>
        <div id='footer'>This is a footer</div>
    </div>
</body>
</html>

I've been experimenting with some other css styling, and I think I almost have a layout that could be cross-browser compatible. I'll post it if I'm not too late.

Azmisov
As a side note, the way I believe HTML should be designed is in small chunks. The html design you have laid out is sort of all left out in the open, without a home. I would much rather put everything in a page_container div, and then wrap all the page contents in a contents div. Then you could break up the contents into smaller chunks like sidebar1, sidebar2, mainbar, etc...
Azmisov
One more note: the only other way I can think of doing it would be with a min-height:100% on the contents div. Apparently, however, specifying a min-height prevents any negative-margining/border-box styling. If there were a way to fix that, you could avoid using display:table and make it cross-browser.Another note: the height:100% on the page container doesn't work when a doctype is declared. You'd have to look into that for a fix, since I don't know one off the top of my head.
Azmisov
@Azmisov: There is a new CSS3 property 'box-sizing' that you can set to 'border-box' that will include padding and borders in the specified width instead them adding to the width. http://reference.sitepoint.com/css/moz-box-sizing
Jason Christa
It doesn't work if you have min-height:100%; set. I guess the link says that too. I wonder why that is?
Azmisov
A: 

Okay, here is the alternative css that I was talking about. It works in Firefox, Safari, and Chrome. IE7/IE6 don't work, you'd probably have to a little tweaking to get that working. Opera has a small bug with the body margins. Other than that, it uses just basic CSS (unlike the display:table that isn't very compatible).

<html>
<head>
    <title>Test page</title>
    <style>
        body{
            margin:0px;
            background-color:green;
            margin-top:75px;
            margin-bottom:25px;
        }
        #page_container{
            max-width:700px;
            margin-left:auto;
            margin-right:auto;
            position:relative;
            height:100%;
            padding-top:75px;
            margin-top:-75px;
        }
        #header{
            background-color:red;
            text-align:center;
            font-size:25px;
            font-weight:600;
            height:75px;
            z-index:2;
            position:absolute;
            top:0px;
            width:100%;
        }
        #contents{
            background-color:yellow;
            width:100%;
            min-height:100%;
        }
        #footer{
            background-color:blue;
            height:25px;
        }    
    </style>
</head>
<body>
    <div id='page_container'>
        <div id='header'>Title of your page</div>
        <div id='contents'>
            Foo bar baz<br/>
            Foo bar baz<br/>
            Foo bar baz<br/>
            Foo bar baz<br/>
            Foo bar baz<br/>
            Foo bar baz<br/>
        </div>
        <div id='footer'>This is a footer</div>
    </div>
</body>
</html>

Wow, if you just tweaked it a little and made it IE6-7 compatible, you'd be famous. I think this is the first solution I've seen.

Azmisov
Does not work on IE8 as well, but a real nice solution!
JochenJung
You're relying on quirks mode??
meder
@meder: Does using the plain <html> tag put you in quirks mode? I didn't think it did.
Jason Christa
Not using a doctype puts you in quirks mode.
meder
Whats wrong with quirks mode?
Azmisov
@azimov - bad question. Lets see if you can find a solution that works with html5 doctype.
Sorin Sbarnea
A: 

You could easily modify the use of this to work for you: Float div to bottom of screen

That post describes how to set a div to the bottom of the page on any circumstance. Just make the footer that div that you push down.

s_broderick
Unfortunately that solution seems to push the div down too low and a scrollbar shows up.
Jason Christa
By increasing the margin-top you can raise it to exactly where you want it. That may help. Do you have an example live something that I could look at?
s_broderick
A: 

If you want a stick footer, you can look at how the css framework Compass does it. Or you can also use the multi browser support option, as describe here. The later has the advantage of having very simple and clear css and associated minimal html.

Daniel Ribeiro
A: 

Since you mentioned that your solution worked except for IE, all you need to do is use JS to enable the styling of HTML 5 elements:

http://medero.org/finally.html

That would make the styles apply, but it still looks like, at least in IE6 it needs some extra help.

Is this close to what you need for IE?

meder
Luckily, I have ceased caring what it looks like in IE6. I feel if the markup is semantic it won't look pretty but any on IE6 will still get the idea.
Jason Christa
Can you check if it works in IE8?
meder
@meder: The shim works because the elements are colored, but IE8 must have display inline as the default instead of display block because except for the footer being at the bottom it is laid out different.
Jason Christa
right, all one would need to do is add css rules to make em `display block: article, nav, aside { display:block; }` ( and the other elements )
meder
+2  A: 

Given the requirements of no extra markup and not caring about IE (does work in IE8), I present this solution (which does require the use of a fixed height header). I did have to use float rather than display: inline-block as my Safari 4.0 did not display it with min-height for this solution:

   <style type="text/css">
        * {
            margin: 0;
            padding: 0;
        }

        html {
            height: 100%;
            }
        body {
            height: 100%;
            /*below for illustration only*/
            background: yellow;
            }

        #Header {
            position: relative;
            z-index: 1;
            height: 60px;
            margin-bottom: -60px;
            /*below for illustration only*/
            background: red;
            opacity: .8;
            }

        #Article {
            float: left;
            min-height: 100%;
            width: 69.9%;
            vertical-align: top;
            margin-bottom: -30px;               
            /*below for illustration only*/
            background: blue;
        }

        #Aside {
            float: left;
            min-height: 100%;
            width: 30%;
            vertical-align: top;
            margin-bottom: -30px;               
            /*below for illustration only*/
            background: green;
        }

        #Article:before,
        #Aside:before {
            content: ' ';
            display: block;
            height: 60px;
            width: 100%;
        }

        #Article:after,
        #Aside:after {
            content: ' ';
            display: block;
            height: 30px;
            width: 100%;
        }

        #Footer {
            position: relative;
            z-index: 1;
            height: 30px;
            margin-top: -30px;
            clear: left;
            /*below for illustration only*/
            background: pink;
            opacity: .8;
        }
    </style>

HTML is just:

<body>
    <div id="Header">Header</div>
    <div id="Article">Article</div>
    <div id="Aside">Aside</div>
    <div id="Footer">Footer</div>
</body>
Scott
You have a vote from me because this was the only solution that respected the requirements and worked on 4/5 browsers. The only problem is that on IE it looks so bad that is not usable at all. Ca you do something for IE to make it acceptable (doesn't have to work, but it should not make the page unreadable).
Sorin Sbarnea
If you feed IE7 (probably IE6 too, though have not tested yet... note it should be working in IE8) css that zero's out every negative margin in all four regions, then you have a readable file.
Scott
With javascript, of course, you could simulate the `:before` and `:after` and have it work in all the browsers, but you would still want the default readable without script working.
Scott
You forgot to include the "lorem ipsum" text in order to test how it does behave when you resize the page. Also more important you forgot to add <!DOCTYPE HTML> - this will solve the rendering in IE7 !
Sorin Sbarnea
Well, I didn't really forget. The above was not intended to be a 'drop in place' solution (i.e. including `DOCTYPE`, etc.). I still have rendering issues in IE7 even with the `DOCTYPE` declared (I have a `DOCTYPE` in my test). The "lorem ipsum" was not originally in his post, so I never copied it over but used my own text to test with full content. I'm glad the solution is working for you.
Scott
That is an interesting solution to overlay the header and the footer. Here is my solution for the moment that doesn't worry about having equal height columns, http://files.nextscreen.com/test.html .
Jason Christa
@Jason: Your `body` does not fill the height, so any background image or color placed on it will not fill the screen if the text is too short to push the footer down. Depending on the implementation, that may or may not be a problem. It is interesting. It seems as though the `min-height` `position: relative` and `height: auto` have zero effect in Firefox (I can take them away and it still is rendering "correct"). I'm not sure why the `footer` is not defaulting to aligning to the bottom of the `body` and `html` (both of which are less than screen height in my test of your page).
Scott
@Jason: I stand corrected, something is happening by setting `min-height` and `position: relative` on the `html`, because if one is set, but not the other it does not work (however, if both are not set, it also works).
Scott
This works fine in Webkit and even works in Firefox without the reset stylesheet (as long as you kill the margin and padding). So there must be some css property that would make the body grow to its full height.
Jason Christa
@Jason: There is a property to make the `body` grow to full height, `height: 100%`, but the problem is then your `padding-bottom: 30px` on the `body` makes the `body` larger than window size and your footer never sits at the bottom of the window like you desire for short content. I'm sure you are aware of all this already, I only point it out to say that is the only way to make the `body` "grow to its full height."
Scott
@Scott: Oddly enough setting height to 100% in Firefox cause more problems. The footer can rise to be in the middle of content. So it appears in some cases height auto > height 100%.
Jason Christa
@Jason: Yes, because the footer is then being set to fit the body height, which is only the height of the window plus the 30px of padding. That's my point, your solution does not allow for the body to fill the height for short content like mine does.
Scott
@Scott: I updated my test to work better. I think it works in Webkit, FF, and IE.
Jason Christa
When I shorten your content, the footer forces me to scroll. Do you not get that effect (Firefox)?
Scott
@Scott: I don't get a scrollbar until the footer touches the article but that is because there is no more vertical space on the screen to show both the contents of header->article->footer without a scrollbar. Do you get one before then?
Jason Christa
I'm at home right now, and here, my Firefox (on a PC) shows it as you state. But at work, my Firefox (on a Mac) showed a scroll bar. I'll have to double check that tomorrow.
Scott
@Jason: Okay, Firefox and Safari on my Mac was showing the footer pushed down, but what was causing it was the top margins on both the `body` and the `h1` tag in the header. With those set to 0, I can confirm that your solution works also. I you change your answer or submit a different answer with the corrected code, I'll give you a +1 vote, as it also meets the criteria for your original request.
Scott
@Scott: The YUI reset.css is supposed to zero those out.
Jason Christa
@Jason: Fair enough... at work, that site is blocked from my access, so therefore it was not loading the reset.css :-)
Scott
+2  A: 

Here is my HTML5 footer example: http://blog.i18n.ro/test/html5-footer.html

WORKS:

  • FF 3+
  • IE7, IE8, IE9
  • Chrome 3+
  • Safari 3+
  • Opera 10+.

DEGRADES on:

  • IE6 (meaning that it will look fine, but the footer will not be at the bottom)

LIMITATIONS:

  • footer height is hard-coded and if you want to change it you have to modify in 2 places.
  • assumes that you have <article><aside><footer> structure. It would be nice to have a JS solution that does not require this structure.
  • the element does not wrap on small resolutions (mobile), but maybe someone will find a solution for this.

I did not include the code here because current wiki is not able to deal properly with HTML code.

This example is based on what Scott posted but solves the IE issues and adds HTML syntax.

I would really appreciate if you could find ways to improve this. Even if it does make minor improvements to the old browsers.

Version 1.1

Sorin Sbarnea
I like you new addition, the popup for old browsers :D
bogdan
Does this work for you, http://files.nextscreen.com/test.html ?
Jason Christa
A: 
Zuul
Zuul: your solution did not work. If I fill the "Article" with text then the "Footer" does not 'push down' but remains at the original window height which ends up being in the middle of the "Article"'s content.
Scott
Just edited the code to fix the overflow on Article and Aside div.
Zuul
That works if a person doesn't mind that the scroll bars show up on the two divs separately as opposed to the whole page. However, the solution does not quite fit the spec's of the desire as laid out in the question. Jason wanted the footer to be pushed down when the content was tall enough to fill the screen, but remain fixed at the bottom for short content. Your solution keeps it fixed at all times.
Scott