Height of div under div with negative margin not reaching bottom window edge

I suppose the summary pretty much says what my issue is. I would provide a link but this particular page only works if you have login credentials, so I included a screen shot. You can see the location of the footer is way up high but the bottom of it should hug the window. The white content is split into two divs, one that includes the text menu and the rounded white corners, and the one under it (the one I can’t get to expand to the bottom of the window) that holds most of the content. The footer uses a negative margin to push on top of the white content div above it. This white-content div also has a padding-bottom value to match the negative margin. the body background is the gray you see at the bottom under the green (top-stripe) div. So the basic html structure:


<body>
    <div id="top-stripe">
        <!-- holds green background with glows -->
        <div id="top-content">
              <!-- has a set width to contain all the content on the stripe -->
        </div>
    </div>
    <div id="white-top">
    </div>
    <div id="white-content">
    </div>
    <div id="footer">
    </div>
</body>

and my css file is pretty full so i’ll just include the css that applies to the divs mentioned above:


#top-stripe {
	background: rgb(69,112,43) url(images/top_glow.png) no-repeat top center;
	margin: 0 auto;
	width: 100%;
	height: 479px;
	position: relative;
}

#top-content {
	position: relative;
	margin: 0 auto;
	width: 1024px;
	height: 100%;
}

#white-top {
	font-family: Georgia, serif;
	margin: -90px auto 0 auto;  /* overridden margin-top: -320px for this particular page */
	background: transparent url(images/white-rect-top.png) no-repeat top center;
	width: 897px;
	height: 139px;
	padding-top: 1px;
	position: relative;
}

#white-content {
	font-family: Georgia, serif;
	position: relative;
	background: transparent url(images/white-rect-tile.png) repeat-y top center;
	margin: 0 auto;
	margin-top: -1px;
	width: 897px;
	/*min-height: 100px;*/
	height: 100%;  /* above didn't work so i tried this...didn't work */
	padding-bottom: 90px; /*offset footer overlap*/
	overflow: hidden; /* necessary for floated content to push bottom edge of element down */
}

#footer {
	background-color: rgb(51,51,51);
	height: 88px;
	width: 825px;
	margin: -88px auto 0 auto;	/*necessary to get shadows on the sides of the footer; overlap white-content*/
	position: relative;
	clear: both;
}

So height:100% doesn’t work. Is this because of the negative margin? I thought it makes the height fill whatever height of the containing object is and technically the body element is the direct parent element of #white-content. Maybe it’s because there’s a different element above it? Ok I’ll stop guessing…can anyone help me out? Btw, this is FF 3.5.7. I suppose I’ll have to worry about the other browsers later. It helps using a reset.css for all my pages.

Hi,

Are you trying to achieve a sticky footer like on this page?
http://www.pmob.co.uk/temp/sticky-footer-ie8new.htm

100% height isn’t that straight forward really - there’s a FAQ on it which explains some of the limitations and tricks to get it to work.

All the best,

Any chain of percentage heights must start with a defined height. Luckily the viewport counts as a defined height. In order to pass on the viewport height, each ancestor to the final percentage min-height must have a percent based height.

(Min-height is not a defined height, so the original height reference is lost for next child.)


html,
body {
    height: 100&#37;;
}
#white-content {
    min-height: 100%;
}
* html #white-content { /* for IE6, height is treated as min-height (as long the visibility is not changed to other than visible) */
    height: 100%;
}


Thanks guys I appreciate the help. The footer reaches the bottom of the window now, but after applying ErikJ’s suggestion, the white-content div now has some sort of super height. Even if there is little to no content inside, it still spans something like 1000px in height. So now I’m getting a TON of white empty space. I applied the css just as ErikJ suggested. Why all the extra space?

Well the #white-content will be 100% height of hte viewport (in this case since that is the nearest parent with a height set). That’s the purpose of a sticky footer. Have the footer at the bottom of hte page even with lttle or no content.

If you don’t think that’s the problem here then please give us a link to the page for easiest debugging :).

Well It’s fine if there’s no scrollbar present on the window. But it’s stretching the white-content beyond the boundaries of the bottom of the window creating a scrollbar on my window. It’s just extra space and I actually have to scroll down to find the footer (even though it does end up sticking to the bottom by the time i get down there).

Unfortunately as I mentioned before sending a link won’t help because login credentials are required to visit that particular page. Since having those credentials provides quite a bit of control I don’t feel comfortable posting them in a thread. The only workaround is to send them in a PM…=\

I was thinking, does the fact that on some of these pages I have set the #white-top div’s margin-top to -320px? Does it calculate height on elemtns with a negative margin somehow differently than if it had a regular margin under the #top-stripe div?

Hi,

We’d need to see your revised code to see what’s going on.:slight_smile:

Perhaps it would also help to identify if you were really ooking for a “sticky footer” or not. If you want a sticky footer then it must be constructed in the manner shown in my demo (that mark linked to) as there is no other way to do it properly.

A sticky footer is one where the footer starts at the bottom of the viewport when there is little content but when content grows the footer moves down with the content below the viewport.

You would need to start with the basic structure then manipulate your images etc to fit within this structure. This still means you can do different effects with shadows and corners etc. I posted a similar example [URL=“http://www.sitepoint.com/forums/showthread.php?p=4489324#post4489324”]in this thread with round corners at top and bottom and shadows (I think the op put a demo up in post #16).

Negative margins won’t change the height of the element as such but depending where they are applied they will either pull the element in one direction or pull other content inside the element itself causing an overlap.

100% height is explained in the faq and is a tricky concept to understand at first and usually doesn’t do what people expect.

You can’t add padding to the 100% high element either or it will be too big.

If you can provide your html and css in a semi working order it will be easier for us to debug. If not perhaps a screenshot of what you are trying to achieve would help.

It looks to me as though your top stripe should be applied to the body element instead or at least placed absolutely behind the actual layout so as not to interfere if it is just a background.

Looking at the code you posted above you would probably have to make something work from within a structure like this.


<!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">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style>
html, body {
    height: 100%;
    margin:0;
    padding:0;
}
#top-stripe {
    background: rgb(69,112,43) url(images/top_glow.png) no-repeat top center;
    margin: 0 auto;
    width: 100%;
    height: 479px;
    position: relative;
    z-index:1;
}
#top-content {
    position: relative;
    margin: 0 auto;
    width: 1024px;
}
#white-top {
    font-family: Georgia, serif;
    background:#fff url(images/white-rect-top.png) no-repeat top center;
    width: 897px;
    height: 139px;
    padding-top: 1px;
    position: relative;
}
#outer {
    width: 897px;
    margin: -479px auto -90px;
    min-height: 100%;
    background:yellow;
    position:relative;
    z-index:2;
}
* html #outer {
    height: 100%;
}
#white-content {
    font-family: Georgia, serif;
    position: relative;
    background: url(images/white-rect-tile.png) repeat-y top center;
    margin: 0 auto;
    margin-top: -1px;
    width: 897px;
    padding-bottom: 90px;/*offset footer overlap*/
}
#footer {
    background-color: rgb(51,51,51);
    background:red;
    height: 88px;
    width: 825px;
    margin:0 auto;
    position: relative;
    clear: both;
    z-index:3;
}
/*Opera Fix*/
body:before {/* thanks to Maleika (Kohoutec)*/
    content:"";
    height:100%;
    float:left;
    width:0;
    margin-top:-32767px;/* thank you Erik J - negate effect of float*/
}
#outer:after {/* thank you Erik J - instead of using display table for ie8*/
    clear:both;
    display:block;
    height:1%;
    content:" ";
}
</style>
</head>
<body>
<div id="top-stripe">
    <!-- holds green background with glows -->
    <div id="top-content">
        <!-- has a set width to contain all the content on the stripe -->
    </div>
</div>
<div id="outer">
    <div id="white-top"> </div>
    <div id="white-content"> </div>
</div>
<div id="footer"> </div>
</body>
</html>


Everything has to be done within the 100% element and if you want shadows etc you have to be creative and work from within the 100% in most case.

Hey Paul. Thanks for taking the time for such a lengthy response. I have now learned a bit more about sticky footers. I added the outer div to all my pages and all the extra space disappeared and the sticky footer appears as expected. However, I ran into a single bug on one of my pages. The footer is still stickied but the white-content div does not stretch to the bottom. I will say that I applied all the css rules you provided as changes in my code. My only attempt at getting the white-content to stretch was to add min-height: 100% and height:100% to my rules, but it had no effect. I have attached a screen shot to show what’s going on with the yellow outer div, the white white-top div, and the blue white-content div.

You mentioned that padding can screw things up but if I get rid of the 90px padding at the bottom of the white-content div it shrinks even more and the footer no longer stickies to the bottom. What is causing my white-content div not to stretch? Why only this page? :frowning:

EDIT: I’d also like to mention the reason why I have the stripe. I wanted the screen divided into two sections no matter how wide someone’s viewport is. So the gray under the green is the body background, and the only way to make the green happen is with the top stripe always stretching 100% wide with the top glow image that will eventually blend with the green color if the viewport is wide enough. I think the top content isn’t as necessary now since I have the outer. I hope my rationale makes sense and if there’s a better solution I’m all ears!

Can you post your current code instead of attaching an image? Or maybe a link preferably?

Hi,

The white content div will not stretch to the bottom because it has no height and you cannot apply height:100% or min-height:100% to it for the reasons explained in the 100% height faq (either you would get another 100% height making the page twice as big as you want and fixed to a size that won’t expand or it would collapse to nothing anyway depending on browser).

Suffice to say as I mentioned above you get one shot at a 100% high layout and everything must be done on the first container which is the only one that can carry the height successfully.

In the example code I posted you will see that I specifically coloured the main containers background “yellow” to show that it does reach the bottom of the page. This is the element that you would need to make white to give the 100% height effect. As I said everything has to be done on this element and if you want repeating shadows etc then they would also need to be included on this element along with the background colour perhaps in a repeating slice.

That may of course leave you with a repeating graphic showing in places that you don’t want but this is easily fixed by just covering up those parts with existing elements where possible.

There are other methods for achieving this effect but I think you can do everything you want without them at the moment.

If I get a few minutes spare I’ll knock up another demo closer to what you want.

Ok - this is very rough as I didn’t have any images to work with.

http://www.pmob.co.uk/smola/smola.htm

That should give you the layout you were looking for. The only problem is that you will need to make sure that the image you place underneath matches the one that I put in the header because there is no other way to do it with the transparency and shadows etc. I’ve put a dummy image underneath so that you can see it will work as long as it matches with the header image and sides etc.

IE6 doesn’t understand transparency so you will either have to give it non transparent images instead or images without shadows as in my example above.

If you want to place anything else above the header then absolutely place it there from within the header itself and place it outside similar to the way I have placed the hello gif to the right side.

The page contains all the elements you need to finish your design and you have to make it work from within that structure. You can’t suddenly add another coloured content div and expect it to go all the way to the bottom because css won’t do that normally.

Hey Paul and RyanReese,

Sorry it has taken me so long to respond. My full-time job has kept me from working on the site. I want to thank you for all the help and direction you’ve given me. It has provided some real insight on the issue of 100% height and sticky footers.

That being said, I believe I have found a solution, and I’d like to know what you think. Here is a link to a demo page I was working with:

http://perksforwork.com/grr.php

You can see all of the css using firebug. I’m just going to post the basic HTML and explanation.

OK, so Paul told me twice that I needed to make everything work WITHIN the #outer div. So I set out to do just that. The 100% rules are applied just as he specified. I started out with his idea of tiling the white-rect-tile image with the shadows as the background of the #outer div. So I changed a rule and the tile went from the top of the viewport to the bottom. That’s no good. I thought that I could specify a starting position for the tile so I tried to vertically tile it starting 320px from the top and 0px from the left. I figured it would tile downwards starting at the position I specified. And you already know that it didn’t work that way :blush:. But I couldn’t have that background-image all the way up to the top of the page. I needed a solution. What I came up with was this:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title></title>
	
	<link rel="stylesheet" type="text/css" href="../reset.css" media="screen" />
	<link rel="stylesheet" type="text/css" href="../css_index.css" media="screen" />
	<link rel="stylesheet" type="text/css" href="css_whoweare.css" media="screen" />
	
	<style>
	
       #top-stripe {
	background: rgb(69,112,43) url(images/top_glow.png) no-repeat top center;
	margin: 0;
	width: 100%;
	height: 479px;
	position: relative;
	z-index: 1;
}

	#outer {
		border: 1px solid yellow;
		width: 879px;
		margin: 0 auto;
		padding: 0;
		background-color: transparent;
		background-image: url(images/white-rect-tile.png);;
		/*background-repeat: repeat-y;*/
	}
	
	#white-top {
		margin: 0;
		width: 825px;
		height: 89px;
		position: absolute;
		left: 0;
		bottom: -55px;
		border: 1px solid black;
		padding: 40px 27px 10px;
	}
	
	#content {
		padding: 55px 27px 110px;
		border-bottom: 1px solid red;
	}
	
	#footer {
		position: absolute;
		bottom: 0;
		left: 27px;
	}
	
	</style>
</head>

<body>

<div id="outer">
	
	<div id="top-stripe">
	
	    <div id="menu"></div>

		<div id="white-top">
		</div>
		
	</div>
	
	<div id="content">
	</div>
	
	<div id="footer"></div>

</div>
	
</body>

</html>

So #footer is absolutely positioned to stick it to the bottom of the #outer div which has a padding-bottom that prevents any content to go underneath #footer or even within 20px of it. Now I won’t need to worry about the side shadows rising up past the bottom of #footer when there is only a tiny bit of content in the Content div. The trick to solve the problem of the repeated background up at the top was to put the #top-stripe div INSIDE the #outer div, effectively covering the top 479px of #outer background. Since the background image of #top-stripe matches the body’s background image, it appears fairly seamless when it comes to the glows near the edges. Then inside the #top-stripe I absolutely positioned #white-top which holds the white rounded corners and set bottom:-50px; only to match the original design (on several pages there is content in the white that is supposed to be partly above the green-gray border and partly below it). Therefore I had to add 50px of padding-top to Content so the content inside it wouldn’t be hidden under #white-top. Since the white shadow technically will always tile from the top of the viewport (albeit hidden by #top-stripe) down to the bottom, and there are appropriate padding rules to prevent any hidden content under the #footer and #white-top divs, the #outer div should expand as more content is added to Content! So it appears that I solved my sticky footer problem!

Concerns:

1.) I have the top_glow image rendered twice (body bg and #top-stripe bg). Since it’s the same image I wouldn’t think that it would take more than the time to load if it were only one image. Maybe only a fraction of a second? I’m not sure.

2.) The background images show up underneath the padding of all my divs. I’m worried about a browser incompatibility that might prevent that effect.

I’m also aware that the borders you see in the demo are offsetting a couple images by a pixel or two, but once I remove them everything should line up. And I still remember your warning that IE6 doesn’t do transparency so the shadows won’t quite work, but I think my clients are OK with that.

What do you think guys? Do you foresee any problems I might have in certain scenarios as I dynamically update pages? What about cross-browser compatibility? It seems to work in FF3.5, IE8, and Safari4.

I’m pretty happy with the solution overall and, again, I really appreciate the time you’ve taken on my issue! :slight_smile: :tup:

Why is the white round corner way down at the bottom of the screen? I’m not sure I understand the logic of the big space above.:slight_smile:

However in essence you have down what I said and repeated the background on the page top element to make a seamless join and rub out the background. That’s the way I suggested in my example and you seem to have followed the instructions ok.

Absolute footers are not very stable in a dynamic environment and if you do a hide and show in the content section the footer will disappear in IE. That’s why my footer method is much better and you could easily have used it as I showed in the demo.

There is however a javascript fix for the absolute footer disappearing and once you have inserted dynamic content (hide and show etc) you must find a reference to the main container and nudge it with some javascript.

e.g.
Assuming outer is the reference to the main container then:


outer.className = outer.className;

The className doesn’t actually have to change for this to work.

Concerns:

1.) I have the top_glow image rendered twice (body bg and #top-stripe bg). Since it’s the same image I wouldn’t think that it would take more than the time to load if it were only one image. Maybe only a fraction of a second? I’m not sure.

An image only loads once and then it is in cache and ready immediately. You can use the same image again without problem or delay.

2.) The background images show up underneath the padding of all my divs. I’m worried about a browser incompatibility that might prevent that effect.

I’m not sure what you mean as padding has no effect on a background image and there are no compatability problems with it.

Hey Paul,

There are some graphic elements in that big empty space. You can peruse a few of the pages that don’t require login credentials starting here:

perksforwork.com/whoweare

Absolute footers are not very stable in a dynamic environment and if you do a hide and show in the content section the footer will disappear in IE. That’s why my footer method is much better and you could easily have used it as I showed in the demo.

You know, I swear that at the time there was a reason I chose to go the absolute positioning route but I can’t for the life of me remember why now! :x I have since switched the the negative margin on the outer div to pull the footer up and it seems to work just fine now.

Thanks for all your help. I couldn’t have done it without you!

There are some graphic elements in that big empty space.

Ok - I wondered why they were there :slight_smile: