How do you keep parents of floated elements from collapsing?

313,707

Solution 1

Solution 1:

The most reliable and unobtrusive method appears to be this:

Demo: http://jsfiddle.net/SO_AMK/wXaEH/

HTML:

<div class="clearfix">
    <div style="float: left;">Div 1</div>
    <div style="float: left;">Div 2</div>
</div>​

CSS:

.clearfix::after { 
   content: " ";
   display: block; 
   height: 0; 
   clear: both;
}

​With a little CSS targeting, you don't even need to add a class to the parent DIV.

This solution is backward compatible with IE8 so you don't need to worry about older browsers failing.

Solution 2:

An adaptation of solution 1 has been suggested and is as follows:

Demo: http://jsfiddle.net/wXaEH/162/

HTML:

<div class="clearfix">
    <div style="float: left;">Div 1</div>
    <div style="float: left;">Div 2</div>
</div>​

CSS:

.clearfix::after { 
   content: " ";
   display: block; 
   height: 0; 
   clear: both;
   *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML += '<div class="ie7-clear"></div>' );
}

.ie7-clear {
    display: block;
    clear: both;
}

This solution appears to be backward compatible to IE5.5 but is untested.

Solution 3:

It's also possible to set display: inline-block; and width: 100%; to emulate a normal block element while not collapsing.

Demo: http://jsfiddle.net/SO_AMK/ae5ey/

CSS:

.clearfix {
    display: inline-block;
    width: 100%;
}

This solution should be backward compatible with IE5.5 but has only been tested in IE6.

Solution 2

I usually use the overflow: auto trick; although that's not, strictly speaking, the intended use for overflow, it is kinda related - enough to make it easy to remember, certainly. The meaning of float: left itself has been extended for various uses more significantly than overflow is in this example, IMO.

Solution 3

Rather than putting overflow:auto on the parent, put overflow:hidden

The first CSS I write for any webpage is always:

div {
  overflow:hidden;
}

Then I never have to worry about it.

Solution 4

The problem happens when a floated element is within a container box, that element does not automatically force the container’s height adjust to the floated element. When an element is floated, its parent no longer contains it because the float is removed from the flow. You can use 2 methods to fix it:

  • { clear: both; }
  • clearfix

Once you understand what is happening, use the method below to “clearfix” it.

.clearfix:after {
    content: ".";
    display: block;
    clear: both;
    visibility: hidden;
    line-height: 0;
    height: 0;
}

.clearfix {
    display: inline-block;
}

html[xmlns] .clearfix {
    display: block;
}

* html .clearfix {
    height: 1%;
}

Demonstration :)

Solution 5

There are several versions of the clearfix, with Nicolas Gallagher and Thierry Koblentz as key authors.

If you want support for older browsers, it's best to use this clearfix :

.clearfix:before, .clearfix:after {
    content: "";
    display: table;
}

.clearfix:after {
    clear: both;
}

.clearfix {
    *zoom: 1;
}

In SCSS, you should use the following technique :

%clearfix {
  &:before, &:after {
    content:" ";
    display:table;
  }

  &:after {
    clear:both;
  }

  & {
    *zoom:1;
  }
}

#clearfixedelement {
    @extend %clearfix;
}

If you don't care about support for older browsers, there's a shorter version :

.clearfix:after {
    content:"";
    display:table;
    clear:both;
}
Share:
313,707
Nathan Long
Author by

Nathan Long

I code mostly in Elixir, sometimes Ruby. More about me at nathanmlong.com and Stackoverflow Careers.

Updated on April 20, 2020

Comments

  • Nathan Long
    Nathan Long about 4 years

    Although elements like <div>s normally grow to fit their contents, using the float property can cause a startling problem for CSS newbies: If floated elements have non-floated parent elements, the parent will collapse.

    For example:

    <div>
      <div style="float: left;">Div 1</div>
      <div style="float: left;">Div 2</div>
    </div>

    The parent div in this example will not expand to contain its floated children - it will appear to have height: 0.

    How do you solve this problem?

    I would like to create an exhaustive list of solutions here. If you're aware of cross-browser compatibility issues, please point them out.

    Solution 1

    Float the parent.

    <div style="float: left;">
      <div style="float: left;">Div 1</div>
      <div style="float: left;">Div 2</div>
    </div>

    Pros: Semantic code.
    Cons: You may not always want the parent floated. Even if you do, do you float the parents' parent, and so on? Must you float every ancestor element?

    Solution 2

    Give the parent an explicit height.

    <div style="height: 300px;">
      <div style="float: left;">Div 1</div>
      <div style="float: left;">Div 2</div>
    </div>

    Pros: Semantic code.
    Cons: Not flexible - if the content changes or the browser is resized, the layout will break.

    Solution 3

    Append a "spacer" element inside the parent element, like this:

    <div>
      <div style="float: left;">Div 1</div>
      <div style="float: left;">Div 2</div>
      <div class="spacer" style="clear: both;"></div>
    </div>

    Pros: Straightforward to code.
    Cons: Not semantic; the spacer div exists only as a layout hack.

    Solution 4

    Set parent to overflow: auto.

    <div style="overflow: auto;">
      <div style="float: left;">Div 1</div>
      <div style="float: left;">Div 2</div>
    </div>

    Pros: Doesn't require extra div.
    Cons: Seems like a hack - that's not the overflow property's stated purpose.

    Comments? Other suggestions?

    • Herb Caudill
      Herb Caudill over 15 years
      I didn't know about the overflow:auto trick - I'd always used the clearing div approach. Thanks for the tip.
    • Donvini
      Donvini over 14 years
      Tip: Solution 4 seems to work for Firefox 3+, but not IE7. For that you need solution 3
    • Doug Molineux
      Doug Molineux about 13 years
      Thanks for the info, I went with 3, couldn't get the first solution to work, perhaps I had a parent parent without float, like you suggested :)
    • Jake
      Jake almost 12 years
      Positioning the parent is another option. e.g. giving it 'position:absolute' or 'position:fixed'
    • Rodolfo
      Rodolfo over 11 years
      as seen here stackoverflow.com/questions/11830433/… overflow:auto seems to have some issues where it adds scrollbars where there shouldn't be any, so instead use overflow:hidden
    • A.M.K
      A.M.K over 11 years
      @Nathan Long, would you mind marking my answer as the correct one? It seems to have been accepted otherwise.
    • BoltClock
      BoltClock over 11 years
      Regarding the overflow property, you may be interested in my answer to the following question: Why does overflow: hidden have the unexpected side-effect of growing in height to contain floated elements?
    • Chris Redford
      Chris Redford almost 11 years
      +1 for the overflow: auto. That's the only one that worked for me.
    • TURTLE
      TURTLE almost 11 years
      overflow: auto; was exactly what I was looking for at this moment in time, You have saved me time and for that you get +1 from me great solutions. It even works in IE 7+
    • MacroMan
      MacroMan over 10 years
      I don't get why browsers render parents with 0 height with child floats. I can understand if the child elements are positioned absolute or fixed, but the behaviour makes no sense in this scenario.
    • Muhammad Umer
      Muhammad Umer almost 10 years
      it'd be great if this oveflow auto worked for absolute position as well
    • Nathan Long
      Nathan Long about 9 years
      Since I asked this question, flexbox has come along. It looks like a great solution for many places where floats were formerly used: flexboxin5.com
    • Lisandro
      Lisandro over 7 years
      Check for missing opening/closing </div> tags! This was driving me mad until I realised I had a closing div without the opener. That was the whole problem.
    • TetraDev
      TetraDev over 7 years
      @Lisandro - you should use an IDE which detects those missing opening/closing tags for you. IntelliJ, visual studio, and many more will save you lots of time by finding these errors immediately during development.
    • carinlynchin
      carinlynchin over 7 years
      any place i can look up why the overflow works on floated?
    • Julix
      Julix over 6 years
      solutions don't belong in questions! - should have edited the top rated solution
    • Nathan Long
      Nathan Long over 6 years
      @Julix While I agree with you in principle, this is a question I asked and updated nine years ago. I had long ago made it a community wiki, leaving it to the community to maintain, and forgotten about it. It's since been closed as a duplicate. If you have strong opinions about it, please feel free to make edits.
    • Julix
      Julix over 6 years
      No strong opinions, sorry for the explanation mark - it overstated my position. "I thought solutions don't belong in questions. Now I'm confused... - Wouldn't the proper way to approach this be to edit the top rated solution?" - is a more accurate representation of my thoughts as I remember them now. - and I didn't even see this is now marked as duplicate. Wouldn't expect that on a 800+ vote item.
    • Gavin
      Gavin over 5 years
      If you're having problems with scrollbars showing when using overflow: auto you can use overflow: hidden instead. Keep in mind anything extending outside of the element will be hidden, including CSS shadows.
    • Usman Iqbal
      Usman Iqbal over 4 years
      Can I ask why this behavior occurs ? whats the root cause ?
    • zdanman
      zdanman over 3 years
      the clear:both spacer (solution 3) works good
  • Nathan Long
    Nathan Long over 15 years
    Oops - I removed the dummy element in the first solution. That was a mistake. Thanks for pointing it out.
  • BoltClock
    BoltClock over 11 years
    This is a bad idea. You don't want to clip anything randomly especially if you set fixed dimensions on those divs. Furthermore, there are cases where overflow: auto is preferred over overflow: hidden (e.g. you want content to be scrollable when it overflows).
  • lededje
    lededje over 11 years
    -1 Inline block with 100% has undesired effects when you have padding on that element. -1 :after doesnt work in ie6
  • BoltClock
    BoltClock over 11 years
    @lededje: IE6 (hell, even IE7) has a broken float model which can never be completely remedied with any sort of clearfix.
  • BoltClock
    BoltClock over 11 years
    Since when did IE6 support display: table?
  • A.M.K
    A.M.K over 11 years
    [rant] See caniuse.com/#feat=css-table, for a full compatibility list. IE 6 and 7 have no support for display: table;. As for your other solution, it's already mentioned in the question which asks for "Other suggestions". Please read the question and all answers before providing your own answer and downvoting others. Another point, invalid CSS may not "hurt" anyone but it's invalid CSS regardless, and vendor prefixes aren't just an accepted norm, look in the Chrome inspector and you'll see that it doesn't just consider them invalid, they aren't processed at all. [/rant]
  • A.M.K
    A.M.K over 11 years
    @BoltClock Quite true, I also never actually tested these in actual versions of the browsers, I use(d) the Adobe BrowserLab.
  • A.M.K
    A.M.K over 11 years
    @lededje You may have a valid point but i'm not supposed to do all the work for you. You can test these methods and if they don't work for you find another solution or just change them, they're not that hard to understand.
  • lededje
    lededje over 11 years
    [response to rant]First of all, the above methods are tested back to IE6 and they all work just fine. Supply a non-working example and get back to me. Vendor specific rules are not meant to be processed in browsers that they don't apply to (that's what vendor specific means...) So yes, of course they are not going to be processed... that's the point, but it still allows you to use bleeding edge css rules.[/response to rant]
  • BoltClock
    BoltClock over 11 years
    That your display: table method works in IE6/IE7 has nothing to do with display: table and everything to do with zoom: 1. See jsfiddle.net/BoltClock/h9GAZ/2 (removed zoom: 1) and jsfiddle.net/BoltClock/h9GAZ/3 (removed display: table). Coupled with the statement "Requires invalid css [for] IE6 and 7", that is akin to saying that method doesn't work in those versions at all.
  • lededje
    lededje over 11 years
    Zoom:1; is not valid css any more?
  • BoltClock
    BoltClock over 11 years
    zoom was never in any CSS specification... it was created and used by Microsoft alone.
  • lededje
    lededje over 11 years
    Making it invalid CSS...? I don't know where you are going with this; it is not useful nor is it going to amount to anything. The above answer works, end of.
  • tybro0103
    tybro0103 over 11 years
    Since I posted this, I have stopped using that as a global default. I do think that overflow:hidden is most often the best solution. Every case is different. Thanks for pointing that out ;)
  • BoltClock
    BoltClock over 11 years
    No problem - I thought I'd add the comment anyway for posterity, in case it ever comes up again.
  • BoltClock
    BoltClock over 11 years
    My point is that you're saying display: table works in IE6+, which is completely untrue. The zoom: 1 patch is there for its own sake and has nothing to do with display: table, so saying the display: table solution works in IE6 is misleading at best. I didn't say using invalid CSS is wrong - I don't really care about that either, but on the other hand I do care about misleading answers.
  • lededje
    lededje over 11 years
    I was just distinguishing one from t'other, no need to (as you so professionally put it) [rant] about it. The fiddles are there to give working versions on what I meant in each solution. Please just drop it. OAO
  • BoltClock
    BoltClock about 11 years
    Do you mean to remove the float declaration as well? Because floated elements cannot be anything but display: block.
  • Griffin
    Griffin about 11 years
  • Dany Khalife
    Dany Khalife almost 11 years
    like seriously who cares about IE6 :D IE8, i would understand that but IE6 is too much even for 2012 :P
  • aruno
    aruno almost 11 years
    if you've got something like a Facebook 'Like' box inside your element you'll need to use this method or else when you click 'Like' the Facebook comment box will be cropped.
  • Chris Redford
    Chris Redford almost 11 years
    These solutions just don't work for my page.
  • A.M.K
    A.M.K almost 11 years
    @ChrisRedford If you are having any specific issues, please ask a question on the main Stack Overflow site.
  • Chris Redford
    Chris Redford almost 11 years
    Ah. Well, the overflow: auto solution in the OP worked for me, so I'm just using that.
  • cprcrack
    cprcrack over 10 years
    The display: table solution was actually the only one that worked in my context (Chrome extension injecting CSS in a complex site). Huge thanks for that!
  • andygoestohollywood
    andygoestohollywood over 10 years
    -1 for stating this is a complete answer
  • Darragh Enright
    Darragh Enright over 10 years
    +1 inline-block (with overflow: hidden and padding) works a treat in my case: floating a couple of block elements inside a parent div. yeah, I'm actually developing something for IE6 over here right now. In 2013 o_O
  • Hector Ordonez
    Hector Ordonez about 10 years
    What kind of user-targeting decision makes a project consider IE6 users? Nowadays the represent the 0.1% of Users (w3schools.com/browsers/browsers_explorer.asp)
  • A.M.K
    A.M.K about 10 years
    @MrMe, I personally never develop for IE6 (still have to do IE7 though), but you'd have to develop for it if you're making a website for a company that uses it.
  • Ranjit Swain
    Ranjit Swain about 10 years
    Awesome, like all 3 solutions.
  • chenghuayang
    chenghuayang over 8 years
    I think the content: " "; can be content: "";, which would be more clean.
  • raven
    raven almost 8 years
    Solution 1 is awesome ! I'm really sick of the redundant and meaningless <div class="clearfix"></div>..
  • DavidTaubmann
    DavidTaubmann almost 8 years
    Congratulations, this is exactly the official w3 solution: w3schools.com/css/tryit.asp?filename=trycss_layout_clearfix
  • DavidTaubmann
    DavidTaubmann almost 8 years
    -1 in pro of standards.... as this doesn't inlcudes the official W3 clearfix (w3schools.com/css/tryit.asp?filename=trycss_layout_clearfix‌​), offered in another answer by Bobby.
  • A.M.K
    A.M.K almost 8 years
    @davidtaubmann W3Schools is not by any means official or part of the standards, they are operated by a third-party corporation that is not affiliated with the W3C. Although they've improved a lot over the past few years, many developers still know them as a bad source of information. I'd suggest you look at the MDN or Web Platform Docs (far less comprehensive, but official) in general for docs. I omitted the overflow: auto trick because it's mentioned in the question that asks for other suggestions.
  • carinlynchin
    carinlynchin almost 8 years
    that really is awesome...but does anyone know WHY it works? (the overflow: auto)
  • A.M.K
    A.M.K almost 8 years
    @carine, I don't have any official source to back this up, but as far as I understand, it works like this: An element in its default state lets any content inside of it overflow (overflow: visible), so it really doesn't need to know how tall it is to display properly. Once you set overflow: auto/scroll it needs to calculate its own height to see if it's max-height or maximum available space has been passed. Once that's calculated, it's used in layout and the element no longer collapses, because it now matters how tall it is. I hope that makes sense.
  • A.M.K
    A.M.K almost 8 years
    @Carine It should be the same idea with display: inline-block (which is my only original solution). If an element is inline things wrap around it, so its dimensions in both directions need to be calculated. Setting its width to 100% doesn't affect the layout process so that works as well. AFAICT, the core idea behind a clearfix is to make the parent element's height important to the browser so the calculations are made and the results acted on.
  • D.R.
    D.R. over 7 years
    W3 != W3Schools, actually W3Schools imho hosts very "fishy" content in regards to standard HTML.
  • bloodyKnuckles
    bloodyKnuckles over 7 years
    I have a problem with floats collapsing my div border on ie6. I added height: 0 which fixed ie6 but broke ie7 and up. :( Turns out height: 1% fixes ie6 and doesn't destroy ie7up! :D
  • TecBrat
    TecBrat almost 5 years
    Regarding W3Schools, I think they've gotten at least a little better over the years, but is it important to realize that, like @D.R. said, They are not The World Wide Web Consortium (W3C)