You might be familiar with elements collapsing vertically. If an element only contains other elements that are floated, the parent element will collapse to zero height. We often employ the clear fix for that. But if an element doesn’t contain anything, it can collapse horizontally as well, which can be quite awkward for layout.
Here’s an example of some HTML for a three-column layout.
<div class="grid grid-bad">
<div class="col col-1-3"></div>
<div class="col col-1-3"></div>
<div class="col col-1-3">
I'm the last column.
</div>
</div>
Floats are still probably the most practical way to handle columns for now. We might use a really simple grid system like this:
.col {
float: left;
}
.col-1-3 {
width: 33.33%
}
If you’re like me, you might have a mental model of that something like:
But you might be surprised. Because those first two columns are empty and have nothing else to give them any height, they collapse horizontally. The last column, because it does contain some content, will respect it’s width, but appear along the left, because the two columns before it have collapsed.
When This Might Happen
I came across it recently in a situation where the content of a column was loaded with Ajax. The column otherwise contained nothing, so until that Ajax call was successful and the content added, it was collapsed in width. When the content did come in, it shifted all the columns after to the right. Awkward.
See the Pen gBCfl by Chris Coyier (@chriscoyier) on CodePen
It may never come up for you. Perhaps your columns always contain some kind of content. No big deal then. But if you are making a grid framework, even for yourself, you should probably consider this scenario.
How To Fix It
The columns need some kind of something to give them at least 1px of height. With that, they won’t collapse in width. Sometimes columns have padding, that works fine. If a column has top or bottom padding, or top or bottom border, you’re set. If not for that, you can just set a min-height.
/* Any of these with positive lengths will work */
.col {
border-top: 1px solid white;
border-bottom: 1px solid white;
padding-top: 1rem;
padding-bottom: 1rem;
min-height: 1px;
}
So yeah, not super common, but if you’re making a grid system you might as well have something in there to prevent collapsing.
Dear Chris Sir,
i like your website so much and wait your new post. i have a problem , can u please post a tutorial like this article. 3 different div
if one div have 180px height according to content and 2nd div has 210px height and 3rd div has 399px height according to content. and these three div have float left, can u please post a article that div1 and div automatic 100% like other 3rd div.
sorry for poor english, i m quite new in css, so hope you will go tmy point/ques what i mean to ask.
waiting your co-operate response
manay thanks css-tricks team
You might want to take a look here. Equal height columns
Having your columns as
display: table-cell
and their parent asdisplay: table
will also work for this. Does have it’s quirks though.Thanks for this so lot! I had a bunch of sleepless nights because of these collapses.
I use to set but this might be a better solution.
I like the Nicolas Gallagher Method
Clever and interesting! I’m not entirely sure I understand the positioning of the example in that article, but I think I get the general gist.
Another technique that I really like (actually, I always use it for grids) doesn’t suffer from the collapsing horizontal columns problem: zen grids.
I used to include a non breaking space to create “dummy content” and avoid problems with empty columns but this solution seems to be better. :-)
As you have already said this isn’t a common problem but nice to have in mind if something like this goes wrong. Thanks for the post Chris. As always it is truly awesome stuff.
How about not using floats at all?
.element { display: inline-block; width: 33.333%; }
The problem with inline block layout is that the browser will put whitespace in between the blocks, which can throw off your layout calculations.
Hello,
you can fix it thanks to several methods: https://css-tricks.com/fighting-the-space-between-inline-block-elements/ ;)
I just want to inform you this guy(Muhammed Aslam) has copied your site design from its source code without your permission i think.
His site URL: http://aslamise.blogspot.com/
Please check it….
I have an entire course on this site that goes through every detail of how this site was designed and built, so it’s pretty understandable.
I know that’s often frowned upon though, so thanks for the heads up.
I’m going to buy this because it doesn’t have anything to do with the content of this article.
@Ahmed Shawan – https://css-tricks.com/license/
Sir,
I’ve an off-topic if you answer it, i’d be extremely helpful:
“How i can disable a hyperlink using only javascript where the href will be remaining within a div tag under a class”
The Forums is a good place to ask that. I’m again going to bury this thread because it doesn’t have anything to do with the content of this article.
Nice. Actually there is a method for layout called something like – faux absolute positioning. It works perfectly with this problem and also allows order columns differently than source order.
thanks a lot for this solution :)
Really Great. I never had a situation like that, but I am ready now, if it ever arises. Thanks.
Good read Chris, It’s a good method. Thanks for post this solution.
Nice trick. Can you can also prevent this problem by placing columns inside a container with a fixed width?
Nice simple tip. I always have solved this in the past by setting a width.
Never thought of using padding or border, but that’s a great idea.
min-height is my preference to prevent collapsing as you columns will still remain transparent.
[class*=”col” ] { min-height:20px; }