Overflow does some cool things you should know about.
- Creates Block Formatting Context
- Clears Floats
Generating block formatting context
Arnaud Gueras called this “contexte de formattage” years ago, and I was kind of surprised when I moved back to the US how few developers here had heard of this “secret weapon”. When the overflow property is set, a new block formatting context is created. What does that mean? It changes the way the block interacts with floats. It no longer wraps around floats, but rather becomes narrower.
Without the effect
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
With new block formatting context
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with ‘overflow’ other than ‘visible’) must not overlap any floats in the same block formatting context as the element itself.
W3C, CSS 2.1
This is not a hack, it is all in the spec from the w3c.
Sweet, so how can you use it?
A block with a new formatting context takes all the remaining space on a line, while leaving room for floats which have already been positioned. In my object-oriented CSS open source project I use the formatting context in two ways.
-
Main content column – adding a formatting context means that my main column takes all the space that remains after my left and right columns have been rendered. This means having only one template because if you want to remove a column from the three column layout, you simply delete the column from the html. No changes to make anywhere else, CMS developers will love you for that.
Play with the template in Firebug.
- Try adding the class “liquid” to the “page” element.
- Add or remove one of the columns from the HTML.
- Extend one of the column objects with the additional classes listed in the documentation.
- Try changing the width of the column directly in Firebug.
- Grids – anyone who has developed a grids system knows the pain of sub-pixel rounding errors. Browsers don’t know what to do with 33.3 pixels, so they all do something different. The YUI grids system hid these differences in the gutters between the blocks, but we can also hide that difference inside the units themselves.
A new block formatting context can be used to make the last unit in any grids line absorb the tiny differences in size. Play with the grids, you’ll notice that as you modify the sizes of the units, the last unit grows and shrinks to accommodate the difference. It has no width, and yet, with a new block formatting context is also doesn’t wrap around floats.
Clearing Floats
You have probably heard about clearing floats. People have been talking about clearing floats via the overflow property for a while now. Some consider it hacky, but a careful reading of the spec shows that while this may not have been expressly intended by spec authors, it was a reasonable interpretation by browser vendors.
In order for them to calculate what overflowed the bounds of the block (and thus should be hidden), they needed to know the size of the block. Because these blocks do no have an explicit height set, the browsers used the calculated height of the content instead. For more information on clearing, see this conversation Eric Meyer and I had on his blog.
Caveats
Overflow can clip bits of too big content (like giant images, pre, or tables), I’m now experimenting with overflow: auto versus hidden to see which is a better trade off.
Other work in this Area
Lots of people are working to find solutions to grids to meet different requirements:
- Matt Sweeney of the YUI team is experimenting with inline-blocks
- Thierry Koblentz is playing with the idea of using table-cell
- Lindsey Simon at Google is looking at alternatives to overflow:hidden that would work well for web applications
- Blueprint and 960gs use widths in pixels rather than percent.
Comments
33 responses to “Overflow – a secret benefit”
Cool! didn’t know that.
In my experience using overflow for float clearing isn’t as robust as the older pie clearfix method — setting overflow to auto can make scrollbars pop up if an element has an outline, or gets an outline by recieving focus, and as you say, overflow hidden is a little risky with the clipping it can do.
@Pete – Overflow hidden is robust and the risk of clipping on normal (non application) sites is pretty minimal. Also, if you use normal form elements, they aren’t clipped by overflow hidden. I’m playing with auto now as a solution for webapps. Websites are probably better off with overflow hidden and a container object that scrolls if the content is too big, e.g images, tables, and pre.
Hi Nicole,
it’s really a mystery how those “hidden” CSS features remain unknown by most of the front end developers. It’s really great that we can use overflow:auto in that situation.
It’s true that most of us use overflow:hidden even when it’s not working correctly, in fact I get the impression that only “hidden” is used at all. I rarely see somebody’s using “auto” somewhere, except for canceling the “hidden” value.
Thanks for the very interesting post! I’ll wait for the next one with impatience! Very good work.
Hi Nicole,
I agree, this is a great tool to build robust constructs. And as we discussed, I don’t understand why this approach is not widely used.
As a side note, there are a few other properties that can be used beside “overflow”:
– float,
– position (absolute),
– display (inline-block | table-cell | table-caption)
See: http://www.w3.org/TR/CSS2/visuren.html#block-formatting
In my opinion, the IE “counterpart” is “hasLayout”, and we can see in the list below that there are common triggers:
– position (absolute)
– float
– display (inline-block)
– width (any value other than ‘auto’)
– height (any value other than ‘auto’)
– zoom (any value other than ‘normal’)
– writing-mode (tb-rl)
Note that there are other triggers that are IE7 specific (see http://www.satzansatz.de/cssd/onhavinglayout.html).
@Pete: the clearfix method is – imho – the worse method ever. I believe most people adopted it because it was “cool”, but not because it was “smart”. The fact that it does not create a new block-formatting context in non-IE browsers, but does trigger hasLayout in IE creates *2* very different constructs.
These are so different that you deal with collapsing margin in one browser but not in the other, background painting issues, lateral margin and padding issues, etc. (note to self: write an article about this because there are way too many authors getting into CSS hell because of this).
See http://www.tjkdesign.com/articles/clearing-floats_and_block-formatting_context.asp to compare some methods
@stoimen: “auto” does not cancel/reset “hidden” as the initial value is “visible”, so “auto” would not change the formatting model.
@Thierry – thanks for all the detail. I agree the clear float effect is much less interesting than intentionally triggering a new context. If you do use it to clear floats it is super important to combine it with zoom, so all the browsers are (mis)behaving in the same way.
overflow is also a silver bullet to tame unordered or ordered lists around a left floated image. Without overflow the bullet points disappear in some browser behind the image. With overflow the list including bullets just stays right (except in IE6, of course).
Nicole, for the lazy – what browser coverage does this have?
@John Allsopp – in combination like so:
overflow:hidden; _overflow:visible; _zoom:1;
It works in FF 1.5, 2, 3, Chrome, Safari, Opera, IE 5.5, 6, 7, 8. I don’t remember the version numbers for Opera and Safari, but I’ve been using the technique for the last 4 years or so, so safe to say it works in all versions people are actually using. I use _ to make sure IE5.5 & 6 don’t see overflow:hidden because they clear floats automatically anyway (a bug). Then add _zoom so that those browsers do get a new formatting context because otherwise the object might interact with other parts of the page very differently in different browsers.
@Thierry – I think you asked about that last bit during my talk at the CSS Summit, but I can’t code and talk or talk and think simultaneously. 🙂
Years back I saw an article on Alsacreations about formatting context. (I didn’t keep the link to it, so I’m just guessing this was it).
Hmm… or maybe it was this article from blog & blues about formatting context.
@Nicole: no the bit I mentioned during your talk is about a rule where you have float and zoom declarations together, which I did not really understand has “float” triggers hasLayout.
So my question was: do we really need both in there?
@Thierry Woot! Nice catch, grids will have eight chars less. 😀
It looks like the right margin on a fluid element will collapse into any right-floated element next to it. Try adding a right-margin to the main content block in your example to see what I mean. That would cause problems for any grid-system that both allows right-floating columns and gutters. Is there a known solution that I’m missing?
@Eric Looks like you can use border-right on the main div or margin-left on the right floated div.
I noticed this the other day when I was creating a new site using oocss. I couldn’t understand why I had never seen this happen before. It’s no longer a mystery.
Thanks!
sorry for my english, i’m french 😀
The block formatting context, is not only a good tool to contain floated elements, it allows containers to trap margins of child nodes..
If you have :
You might think that the
h1
is 10px from the top of div. But it’s not the case, the margin on theh1
is collapsed to thediv
.But, if you add formatting context, the
div
will trap margins.Some better explanations in english 😀 : http://www.maxdesign.com.au/presentation/workshop/slide47.htm
If someone could correct my english, thx 😀
@Arnaud – Very good point. I forgot about that. Overflow hidden does prevent margin collapse between a parent and its child nodes.
So wouldn’t that “Trapping margins” trick negate the need for using padding instead of margins in the spacing model in OOCSS? Seems to me like that takes care of most of the problem of margin collapse, and you could take advantage of the sensible part of margin collapse 🙂
Hiya Nicole,
Thanks for this. Was an utter revelation. I’ve seen so many ugly ugly hacks and over-specified cumbersome metrics aimed at achieving exactly this in such inelegant ways, I’m glad I can start saving myself the time and characters immediately. As it happens I am about to rewrite the templates for one of my company’s core web products, and this has plenty of applications in this particular instance.
I personally prefer overflow:auto by default — that way you get scrollbars if the content is too large, without the need for extra markup. I have also found that when it comes to dealing with real overflow content, IE6 will cause the element to clear the float, regardless of whether overflow is auto or hidden: http://barneycarroll.com/dev/test/overflow.html (the first set of boxes contains an overflow:auto as its last child; the second is overflow:hidden)
On a tangential note, what are your opinions on this slightly hacky method for shrinking a block-level box to fit contents and forcing the next block to clear it?
Blahblahblahblah
Blahblahblahblah
Argh. My code got parsed out. Basically the idea is to give the element in question float:left;margin-right:100%; or float:right;margin-left:100%.
I still think using overflow techniques has on balance more drawbacks than the old clearfix method.
Just today, I was building a page using overflow to clear my floats and found my objects getting clipped when using negative margins to ‘pop out’ a contained object. While this behaviour is obvious, it is a fairly undesirable side effect. Add to that use of absolute and relative positioning that would also be cropped; I think I’d rather stick with the clear-fix method, which is not perfect but imo the best compromise.
I think there was at some point a speculative CSS property for clearing floats called ‘clear-after’, but it has since been removed from the draft spec. We need it back, or something like it that is specifically for this task.
@Barney – I had that same bug (IE6 clearing with overflow) yesterday. I nested another div inside with width:100%; overflow-x:scroll. It stops the clearing problem, but the scrollbar is always present (at the bottom). This may be ok for templates, but would be really ugly for grids (imagine little scrollbars popping up all over).
I guess the real solution is not to nest content that is too big, but that is hard in a CMS situation.
@Pete – overflow hidden is better for creating a new formatting context than for clearing floats, I’m also playing with display:table-cell. You can find the latest code on github. http://github.com/stubbornella/oocss/
Very interesting stuff, though I have run into some issues with overflow:auto in IE6 and padding. As a sidenote I was very surprised to see someone so well versed in CSS using IE hacks as opposed to conditional comments. What’s up with that?
[…] Je découvre tout à fait par hasard ce billet de Nicole qui expose une solution très intéressante pour faire des colonnages. […]
Nicole, you’re my latest hero! (or is it heroine?)
I was watching Sitepoint CSS frameworks video and they happened to mention your OOCSS video. So I googled, watched and agreed. I’m in the process of creating something similar at my work and as my masters thesis. So I found your thoughts helpful.
Then I decided to visit your site (nice alias btw) and saw this. Altho I did know about using overflow:hidden to clear floats, I did not know about using it to fill space next to floated element. Thanks!
My question however is, could this be applied to something that needs to have source order like this:
[left]
[fluid center]
[right]
to make this:
[left] [fluid center] [right]
fill the whole available area? (I’m thinking navigation for paging) I’ve always found this a bit hard with floats and flexible sizes.
@Ramon Turro – I think she prefers to have the code all in one place (as an library) and to have one less http request. I occasionally consider using similar methods, but I tend to prefer conditional comments, I just wish we’d have conditional comments inside CSS. (there’s an conditional comment thing for js, but I have not seen a CSS one yet)
@Arkkimaagi Thanks. With display: table-cell you could achieve the source order you suggest, but it wouldn’t work on older versions of IE. Make sure to use a table-row element as well or the whole thing will be totally broken in all browsers.
Just great, thx for sharing this! By the way i love your oocss framework (:
stay tuned for more happy days!
(:hris
I’ve wrote about this method[1] long long time ago, at the time I read the “simple clearing” article by SitePoint.
I called it the “panacea technique”: Just add “overflow:hidden; height:100%;” to any box that needs clearing and your life problems will be solved, even on IE6, without any glitch nor inconsistency.
Regarding the ugly clearfix method, it has been revised recently (well, last December) by PerishablePress[2].
The advantage of the clearfix method over the overflow method is that it’s more “CSS3” friendly, particularly with the box-shadow property. Applying overflow:hidden to a shadowed box will crop the shadow… The clearfix method (new or old) doesn’t have that flaw.
[1] http://forum.textpattern.com/viewtopic.php?id=20059
[2] http://perishablepress.com/press/2009/12/06/new-clearfix-hack/
Thierry explains this situation pretty good here: http://carsonified.com/blog/design/everything-you-know-about-clearfix-is-wrong/
@lonut Popa – wow, Theirry’s explanation is great. Far better than mine. Thanks so much for the link. 🙂
@Nicole: I’ve seen your talk at Velocity 2010, and in the FB example, you are using the same trick with overflow, as described here. But in that example you’ve got overflow repeated twice:
.media { overflow:hidden; overflow:visible; …}
What’s the catch with this?
@ivanhoe That should be:
.media { overflow:hidden; _overflow:visible; zoom:1;}
If one was to create a simple page that has a “header”, “main”, “sidebar”and “footer” couldn’t display: table; be used for parent elements and display:table-cell for child elements just do away with floats and clearing?
Are there workarounds for (Webkit) CSS percentage rounding issues?…
The best way (I’ve found) to handle this is to use percentages across the board, then override the last element with auto width and a new formatting context, causing it to fill whatever remaining space exists. The ‘new formatting context’ [1] is a W…