CSS Positioning Problem
December 23, 2010 4:13 PM   Subscribe

I have a CSS positioning problem. Santa please help solve it!

I am designing a web page and having a terrible time with positioning!

What I want for Christmas is:
1. A bar at top that is 100% width & fixed
2. A header that is 960px wide, centered & fixed.
3. Content below the header that is 960px wide, centered, and relative, so that as content is added, the footer is pushed lower, and also, if the page is scrolled, the content disappears underneath the fixed header above.
4. A footer that is 100% width and fixed, and that moves down the page appropriately as content is added above.

I've basically figured out wishlist items 1, 2, and 3.

Absolutely flummoxed on item 4. Whenever I try to make the footer 100% width, it loses the positioning I want, and becomes relative to the top of the page, not relative to the content immediately above which is what I want. (i.e. the footer slides up over header and the page becomes a total mess)

Here is a mockup of the webpage:

(The footer is currently positioned absolutely, just to demonstrate intent, but as I don't know how much content will ultimately exist between header and footer, this is not a permanent solution)

Here is a picture of my intent:

Please santa!
posted by bonsai forest to Computers & Internet (13 answers total) 2 users marked this as a favorite
I remember having the same argument with my footer recently . . . it was a relatively simple fix, but I had a bunch of other variables that you don't, so it's hard to pick out the culprit.

First, get rid of all the position:fixed declarations! You don't need them. Don't set position at all unless you have to; use float:left instead and you'll solve lots of problems right there.

My first attempt at solving this would be to create a "container" div that wraps around everything (open it just after body and close it just before), then setting that to 100% width. Everything inside - header, content, and footer - should float left and be either 100% width or fixed width+centered. If content is set to height:auto, this should theoretically push the footer down as far as it needs to (and you might want to set a min-height as well).

If that doesn't do it, try setting the container div to position:relative, then the footer div to position:relative and bottom:0.
posted by ella wren at 4:41 PM on December 23, 2010

You could also try using the 960 grid system as a base, since you're using 960 width. Then just use your 100% as elements outside of the grid.
posted by kellygrape at 4:49 PM on December 23, 2010

Are you stringently opposed to the use of tables? td valign="bottom" would fix this in a flash.
posted by ErikaB at 4:59 PM on December 23, 2010

Response by poster: The 'fixed' declarations in the header are so it stays fixed - ultimately I want content to slide up and under the header when the page is scrolled (you can see this effect in my first link). Don't I need this declaration even if I float everything? (I agree that desire for header to be fixed is the root of this problem).
posted by bonsai forest at 4:59 PM on December 23, 2010

Don't you want your #contentcontainer to be absolute rather than fixed?

#contentcontainer {
margin: 0;
position: absolute;
top: 0;
padding-top: 190px;

I'd look up sticky footers, too, to stop your footer floating halfway up the page when there's not much content. It's the sort of design that the footer would look best being sticky. There's loads of solutions out there; just search "sticky footer" and hope like hell one of them is based on markup that matches your HTML's structure!! :)
posted by springbound at 5:59 PM on December 23, 2010

Whoops, sorry, try it with 220px padding-top rather than 190px. I didn't realise I hadn't pushed it down low enough to see the h2 at the top of the content section with 190.
posted by springbound at 6:08 PM on December 23, 2010

Yes, you're right to use fixed in that case - I didn't realize you wanted the content to scroll beneath.

Setting the content container to absolute (or fixed) will guarantee that the footer won't work how you want it to. Absolute positioning basically removes any relationships an element has to anything EXCEPT it's parent, so anything coming afterward (like the footer) will ignore it. This is the opposite of what you want - you want your footer to always float after the content.

If your content will be about the same length on every page, you can get away with being super-rigid about positioning. But you'll save yourself some headaches if you allow for a little flexibility in your layout.
posted by ella wren at 6:31 PM on December 23, 2010

Response by poster: Thanks for the answers so far...I'm still stymied, but maybe on the right track...

*ella wren: I've tried playing around a bit with an all encompassing container div and some of your ideas, but so far haven't found a way to make it make a difference.....

*kellygrape: 960 grid is great as shown - what's different that I am trying to accomplish is that the header is fixed, and all content below would disappear into the dotted line lower border of the header when you scroll up.

The reason I want to do this is I want to implement one of those jquery smooth sliders such that when you click on one of the menu items, the clicked content will scroll up and under the fixed header.

...That's why I want the menu to stay fixed in place on top.

*ErikaB: I've just never used tables, and I suppose I would rather not in non-table situations.

*Springbound: You may just have the lead I am looking for - won't be able to test it out for a day or so, but googling "sticky header" led me to this tutorial, which on the surface looks like it should lead me where I want to go with some modification...(the demo looks close to what I am trying to accomplish...I will post again when I get a chance to try it!)
posted by bonsai forest at 10:26 PM on December 23, 2010

Best answer: I got stuck on a different project, so I thought I'd take a stab at yours, which was far easier.

Here's the test page, I haven't had a chance to test in IE, and used a bit of html5+css3 (though, nothing special for the actual layout), but it should all work if you plug in something like ecsstender. The folder has no index page, so you can take a look at all the corresponding files as well. I used the latest HTML5 Boilerplate as the base (a little overkill, but I do it out of habit). I tried to document everything as well as possible. Email me (in my profile) if you have any questions.

Merry Christmas!

(Time for bed.)
posted by thebestsophist at 12:51 AM on December 24, 2010

Best answer: And by "document as well as possible" I apparently mean "almost not at all."

The pertinent bits:
  1. To give the masthead and the footer full width, you need 1 container for each. Do not put it all in a single container div (more on why below).
  2. I used 3 container elements (more out of laziness, than need) for the header. They were more or less for the two lines at the top. If you make the lines a background image instead of borders, you can get rid of one container div.
  3. Only the outermost container element for the masthead needs position: fixed, treat everything inside as position: relative, it'll just be relative to the things inside it
  4. Don't forget to set z-index:2 for the header, else you'll have a few pixels of text running over your lines, very confusing when you're running onwards of 20 hours.
  5. Instead of giving the first element of the main content a margin (which will pull the header down with it), give it a huge padding-top to push it down below the masthead. It's kind of cheating, but it works.
  6. Treat everything in the main body as you normally would.
  7. The footer needs an extra container div with width: 100%, the inside container has the width and margin: 0 auto;, just like the top.
  8. Don't forget body { background: #fff; }
  9. I did absolutely nothing for the typography.
In short:
  • The masthead has 3 container elements. (A div, a header, then a div.)
  • The main body of content has 1 container element. (A section.)
  • The footer has 2 container elements. (A footer, and a div.)

posted by thebestsophist at 1:17 AM on December 24, 2010 [1 favorite]

Response by poster: thebestsophist: whoa! This looks great - on a train now I'll try to implement tonight...Thanks
posted by bonsai forest at 9:12 AM on December 24, 2010

Response by poster: Thanks again thebestsophist, this so great, and you are so very kind to work so comprehensively on answering my question. I really appreciate it.

I'm not going to be able to implement till after christmas day, but I can see that this is exactly what I asked Santa for! : )

(Curiously it doesn't display properly at all in my iPhone, so I couldn't really see the test page till I got on my laptop....I'm assuming this is something quirky with the boilerplate stuff that will be easy to fix cause it looks great in Safari...Firefox, the branding box doesn't show, but again, I'm assuming this is something simple like the fact Firefox wants the branding to actually be there to display, whereas Safari shows the placeholder div?)

Anyway, I'm confident I can make it work as you did, but thanks also for offering that I email you if I run into a real stumbling block.

posted by bonsai forest at 9:33 PM on December 24, 2010

I glad I could help.

You didn't see the proper layout on the iPhone because I set all the styles using CSS3 media queries which can tell browsers to serve different layout given certain criteria (such as device orientation, screen width, etc). So the styles only applied when you had a window width larger than 960px. Normally, I would have slightly different layouts optimized for 480px, 768px, and +960px.
posted by thebestsophist at 12:23 AM on December 25, 2010

« Older F---ing microeconomics, how do they work?   |   Will it bake? Newer »
This thread is closed to new comments.