Oh, floats. Every web designer have worked with them. Floats let you rearrange the flow of elements. They're powerful, they're useful, they're... painly buggy on old browsers, I know. But they're one of the CSS2 most used properties, so they deserve some respect.
Let's make some fun with floats. We will design a simple menu from nothing more than pure HTML tags and some CSS magic.
<ul>
<h2>Menu</h2>
<li><a href="#">Option 1</a></li>
<li><a href="#">Option 2</a></li>
<li><a href="#">Option 3</a></li>
</ul>
Then we add some style
ul {
list-style:none;
margin:0;
padding:0;
}
h2 {
background:#369;
color:#9CF;
}
li { background:#69C; }
a {
color:#CFF;
text-decoration:none;
}
a:hover { color:#FFF; }
li, h2 {
float:left;
font-size:12pt;
height:2ex;
margin:0;
padding:0.5em;
}
South of the border
Wow, that was a nice improvement, with no HTML markup addition at all. Great! Now that I'm thinking, this <ul> would look even better with a border. Let's do it!
ul { border:2px solid #9CF; }
Oops! That was not what we intended at all!
With some of its children floating around, the <ul> has no idea of its own dimensions and ends like a 0px box. With a nice border, yeah, but kinda useless.
Float the problem
Let's try something. We can float also our little <ul> to tell it to cover all it's children extent
ul { float:left; }
But now the problem bubbles up one level. The parent node of the <ul> isn't aware of the height of it's own content, and thus, does not render correctly. Well, best said, it doesn't render as we would.
.container {
background:#47A;
padding:1em;
}
We surely can put a float:left
in the container and go up again and again until floating left the <body> tag, but I don't think that's a good idea. Let's think deeper.
Clearing
More knowledgeable people thought the same and began to add some additional mark-up to do the clearing with clear: both
. Something on those lines did the trick:
<div class="container">
<ul>
<h2>Menu</h2>
<li><a href="#">Option 1</a></li>
<li><a href="#">Option 2</a></li>
<li><a href="#">Option 3</a></li>
</ul>
<div style="clear:both"></div>
</div>
Well, yeah, it does what we want, but... Hey, you're adding new markup to the HTML. You're polluting our beloved WWW with non-semantical inline-styled tags. Well, it can be done without inlined style, but the most important here is that you are mixing content with style. And mixing things is not always a great idea. Do you remember Diet Coke and Mentos?
Soon the WWW was a field infected with "clearbothitis", since it seemed no one could live without floats and no other solution arose.
Clearfix
Then even more knowledgeable people came with a CSS2 full equip solution. Introducing clearfix!
.clearfix:after {
clear:both;
content:".";
display:block;
height:0;
line-height:0;
visibility:hidden;
}
Of course, with some tons of additional hacks for it to work in some applications. Nice!! Now you only have to put some classes to call the div to order.
<div class="container clearfix">
<ul>
<h2>Menu
<li><a href="#">Option 1</a></li>
<li><a href="#">Option 2</a></li>
<li><a href="#">Option 3</a></li>
</ul>
</div>
And our example turns into:
IE users could experiment strange behaviour viewing these examples. But, hey, you already knew that, didn't you? Go download a decent browser, you Neanderthal!
Yes! This is what we intended. Now nearly every site has it's own clearfix derivative implementation. It's pretty neat, isn't it?
Clearfix drawbacks
Well, yeah, I must admidt it. But, despite me not being a guru, this fix has, for me, some problems:
- Old non-CSS2-compliant browsers can't show it. "Yes", I hear you say, " but they're legacy, you can't support them 'til the end of time". Sure not, I know, but even now there are millions of users browsing the WWW with old browsers. Would you be the one ignoring them? Me neither.
- Well, have I said this needs tons of non-edulcorated CSS hacks in order to work in those 'exploring tools' I mentioned early? I mean IE6 and IE7 with their "hasLayout" neverending stories, of course...
- I can't find the evolution between this and the previous one. You used CSS2? Sure you're a modern web designer! But you're committing HTML4 crimes, because you've polluted your HTML nonetheless! This is not a step forward nor backwards. Is a step aside, in the better case.
Conclusion and overflow
I think my point of view is clear: Markup is for content. There's no room for class="clearfix"
as there is no room for class="blue-left-floating-column-80px-width"
. But every now and then I had to eat my words and thoughts and points of view (and some other non-gratefully things) and admit there is no other way to do the right thing.
Until now, that I read about a new CSS trick:
.container {
overflow:hidden;
width:100%;
}
As simple as this! And it works great. Even in Netscape Navigator 4! Boy, that's too much of a lucky one, isn't it? I wonder if it happens to work with the IE family. It seems it works too. That's EXACTLY the kind of solution I was looking for!
No need for additional mark-up at all. Ever!
Brilliant! Thanks a lot for posting this. Clearfix has been a great solution but it still just felt wrong. This is way better! :)
ReplyDeleteHow do u do if you want overflow visible then?
ReplyDeleteThanks for the comments. @Christian: Could you elaborate and put an example where both clearing floats and overflow:visible are needed? I can't come up with any at the time.
ReplyDelete