Opera body:before float ? (sticky footer)

Ok, I know that the fix for Opera when using the body:before float is an extra inner wrapping div to keep it from clearing any other floats.
http://www.pmob.co.uk/temp/sticky-footer-ie8new.htm

My question is this: Is Opera actually getting this wrong? It seems to be the odd man out in the way it displays the float.

Opera is the only one that will actually show the float when a width and a BG color is set for the sake of testing. (as seen in my code below)

I like setting a bottom padding on the content div rather than a top dummy border on the header with negative top margin on the wrapper. I was able to come up with an AP Sticky Footer that works flawlessly.

Here is Opera clearing the content div (wrongly I assume) while using the clearfix method -
(works as expected in FF and IE)
Any thoughts on Opera and the body:before float?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Sticky Footer</title>
<style type="text/css">
* {margin:0;padding:0;}

html, body {height:100%;}

body {   
    background: #BBB;
    font:100% arial,"trebuchet ms",tahoma;
    color: #000;
}
body:before {/*Opera min-height 100% Fix*/
    content:"";
    height:100%;
    float:left;
    width:20px;/*reset to zero after Opera testing*/
    background:red;/*just for testing with width*/
}
#wrapper:after,
#content:after {/* Float Containment, IE6/7 will need "haslayout"*/
    clear:both;
    content:"";
    display:block;
    height:0;
    font-size:0;
}

/*===  Begin Layout Structure ===*/

#wrapper {
    min-height:100%; /*height is determined from parent's height (html & body)*/
    width:800px;
    margin: 0 auto ;
    border-left: 1px solid #000;
    border-right: 1px solid #000;       
    background: #EEF;
}
#header{
    height:100px;
    background: #8088C6;
    border-bottom:1px solid #000;
    text-align:center;
    font-weight:bold;
}
#content {
    width:100%;/*haslayout*/
    padding-bottom:61px; /*preserve footer space (plus 10px for text spacing)*/
    background:lime; 
}
#testfloat{
    float:right;
    width:200px;
    height:160px;
    margin-right:-40px; 
    position:relative;
    background: #BDC2E2;
    border: 1px solid #000;
}
#footer {
    clear:both;
    width:800px;
    height:50px;
    margin:-51px auto 0;
    border-top:1px solid #000;
    background:#8088C6;
    text-align:center;
    position:relative; z-index:1;
}

/*=== Demo Typography ===*/
h1,h2,h3 {padding:10px 10px 0; text-align:center;}
h1 {font-size:1.55em}
h2 {font-size:1.45em;}
p {padding:10px 10px 0;}
#footer p {line-height:50px; padding:0; font-weight:bold}
</style>

<!--[if (lte IE 6)|(gte IE 8)]>
<style type="text/css">
#wrapper {
    height:100%; /*IE8 needs height:100% with display:table;*/
    display:table; /*IE6 ignores display:table; and sees height:100%; as min-height*/ 
}
</style>
<![endif]-->

</head>
<body>  

<div id="wrapper">  
    <div id="header">
        <h1>Sticky Footer</h1>      
    </div>    
    <div id="content">
        <h2>Page Title</h2> 
        <p>This demo uses no extra markup in the html for Opera and IE8 compliance.<br> 
        IE8 is fed a Conditional Comment that uses display:table; to fix it's min-height:100%; bug.</p>
        <p>Reduce viewport height to scroll content and test sticky footer.</p>
        <div id="testfloat">
            <p>This is just a test float to ensure that #content is containing it's floats.</p>
        </div> 
        <p>Content</p>
        <p>Content</p>
        <p>Content</p>
        <p>Content</p>
        <p>Last Content</p>          
    </div> <!-- end content -->
</div> <!-- end wrapper -->          
    
    <div id="footer">
        <p>Sticky Footer</p>
    </div> <!-- end footer -->

</body>
</html>

Ray I’m a bit cnofused. I’m using Opera 10 and I changed the width as the comment suggested and nothing happened. What were you referring to? I didn’t notice anything obvious.

And Opera’s need for the body:before trick is it’s own rendering fault to begin with.

Opera’s need for the body:before trick is it’s own rendering fault to begin with.
That’s what I was asking about, whether or not Opera is showing the float incorrectly. I was assuming that Opera is wrong thus the reason it works for that browser.

I changed the width as the comment suggested
I got it set at 20px in the code above just for the sake of testing with a BG color. As I said Opera is the only one that shows the float at 20px wide by 100% tall. The comment about resetting it to zero does not pertain to my question in this thread, that was just a note to not use the layout with a width on the float. I set the width to figure out what Opera was doing.

So, this is wrong behavior that Opera is showing?

Yea the trick allows for Opera to do vertical ersizing and by nature that is a rendering fault.
Updating dynamic content-aka in this case-vertical heights has always been Opera’s Achilles’ heel.

Opera is wrong in this case. Technically empty elements (which is what :before injects, but not into the DOM (it can’t be recognized there)) are supposed to be ignored by UA’s but Opera wrongly interprets them and renders them and since it has the details of what is supposed to fix this wrong behavior it acts on iit and thus it is fixed.

Why would it not be shown? Surely it should be shown just like any other :before box?

I see the red float in Firefox and Safari, too.

The wrong behavior in Opera is that without the float, Opera doesn’t reflow when the window is resized. Showing the float is correct behavior.

My understanding of CSS21 is that :before { content:‘’ } generates a CSS box. Indeed, if it didn’t, the Content clear float fix wouldn’t work.

Could you back up this statement?

Which part? That it isn’t recognized in the DOM or that empty elements are supposed to be ignored by UA’s

The first part-just try some tests. I remember it being inaccesssible

Second part-it’s on W3’s site. I did a quick glance over there on possible pages but I don’t want to spend my entire evening combing through their site. I remember reading it on there however.

Yea the trick allows for Opera to do vertical ersizing and by nature that is a rendering fault.
Yeah, I know all about Opera’s redrawing bug and the various fixes that work.

I see it in Safari and it is showing the content div as solid green just like Opera but I don’t see FF(3.0.11) doing this, nor IE8.

As I mentioned above I am aware of Opera’s redrawing issues and that is the reason for the :before float which was developed in the Sticky Footer Quiz.

So now safari is doing the same thing as Opera and I am not seeing the float at 20px x 100% in FF3.

Here is the live code from above
http://www.css-lab.com/test/stickfoot-test.html

zcorpan, which version of FF are you using?

I’m using FF3.5 and I saw it originally though I misinterpreted your original q.

Ok, I see why my AP Example from post #1 is working, I floated the Content div which allowed it to clear the :before float.

I’m just trying nail this down and figure out which browser’s are rendering this body:before float properly. That is the whole point of this thread, so I guess I’m still looking for a definitive yes or no on who is right and wrong.

The only way FF3 or IE8 will show the float is with generated content as shown below but I don’t get 100% height.

body:before {/*Opera min-height 100% Fix*/
    content:"[B]float[/B]";
    height:100%;
    float:left;
    width:20px;/*reset to zero after Opera testing*/
    background:red;/*just for testing with width*/
}

I believe tha tit is only showing because otherwise the content is nothing thus an empty element and that reverts back to my statement about UA’s supposed to ignore empty elements. I know I read that somewhere on w3.

The second part.

The HTML4 spec says that UAs should ignore empty P elements. However that’s quite irrelevant here.

CSS21 says that a static block box with no padding, no border, and auto height and no content will have margins collapse through it.

I don’t know of anything that says that a floated empty box with specified dimensions should be ignored.

Trunk.

[QUOTE=zcorpan;4376363]
The HTML4 spec says that UAs should ignore empty P elements. However that’s quite irrelevant here./QUOTE]

I know that it said elements in general-not just <p> elements. I don’t know whether floats would affect that though.

Hi Ray,

FF3 is buggy with the :before and :after pseudo elements which is why you are not seeing a 100% high float. FF3.5 shows it the same as safari and opera which is as it should be. They fixed those pseudo classes in FF 3.5 :slight_smile:

For the sticky footer Firefox 3 doesn’t need the before float anyway. It’s only to cure the opera resize bug (as you know).

I’ve found in the past that the absolutely positioned footer breaks in ie6/7 when dynamic content is inserted or a hide and show takes place in the content. I just tested on your layout with a quick hide and show and it seemed to work ok but I would suggest you test with a bit more content and a few floats in the layout.

If you use the negative footer method then you can always set a negative bottom margin on the :before float also. I like the border on the header method as it fixes the problem at the start but in effect its the same difference as adding padding to the bottom of the content to protect the footer.:slight_smile:

Hi Paul,
After setting up another Test Case and reading through the specs I came to the conclusion that Opera was correct in it’s display of the :before float. :slight_smile:

I assumed that the problem in FF was fixed in 3.5 after hearing that it behaved as Opera, though I had not confirmed that yet so thanks for the link.

As far as the AP footer I was not aware of the potential problems you mentioned with ie6/7. I’m not trying to reinvent the wheel here I was looking for a way to eliminate the extra inner div that was needed to clear the :before float. But with the problem resolved in FF3.5 it will need the extra div just like Opera and safari does. It seems to be the best solution as it is definitely needed when using the :before float.

Hi Ray, I see you want to loose the extra inner div needed for content elements not to clear the pseudo element. :slight_smile:

Just a thought; Paul mentioned a negative margin on the pseudo element to allow the cleared footer to go up. Have you tried cancel out the pseudo element’s whole effect on cleared elements by a very large negative top or bottom margin on it? Like:

body:before {
	float:left;
	[COLOR="Red"]margin-top:-9999em;[/COLOR]
	width:0;
	height:100&#37;;
	content:" ";
}

Maybe that could make the inner div unnecessary?

Sorry I can’t yet test myself if this could have any side effects in a real layout. :slight_smile:

Hi Erik,

That’s a very good idea and we could actually use margin-bottom:-100% instead to always maintain the correct zero impact.:slight_smile:


body:before {/*Opera min-height 100% Fix*/
    content:"";
    height:100%;
    float:left;
    width:20px;/*reset to zero after Opera testing*/
    background:red;/*just for testing with width*/
 [B]   margin-bottom:-100%;[/B]
}

I’ve tested in opera and it still seems to allow the window to be resized while negating the effect of the float for cleared elements.

Probably needs a little more testing but I think that it will work and reduce the need for the float containment :slight_smile:

Edit:

I updated my example and it seems to work well :slight_smile: Thanks Erik :wink:

Sorry I can’t yet test myself if this could have any side effects in a real layout. :slight_smile:

The Negative-Margin-Master strikes again :slight_smile:

Hi Erik,
I just updated my Live Code with your suggestion and it looks promising as I see no redrawing problem in Opera while using it. Will test further but it appears fine in Opera and Safari, perhaps someone with FF3.5 can take a look at it for me.

LOL Paul! :slight_smile:
We both ran tests and reported back within a minute of each other.

:slight_smile:

I’ve just run some tests in FF3.5 and your one is fine using the top negative margin.

The negative bottom margin works but of course as margins are based on the width of the element it means that if the page is squashed the margin doesn’t reach all the way up.

Therefore the measurement can’t be a percentage value so a 999em negative top or bottom margin will be best ( or use operas pixel limit which I forget off the top of my head - safari is 32767px IIRC). You have to be careful with 9999em as that may break the limit.

This will be useful in bringing the html back to the original mark up and no extra divs needed :slight_smile: