Why `float:left` doesn't work with a fixed width?

21,088

Solution 1

It seems to me that it is the simple rule that blocks, unless floated, always start a new line. w3.org/TR/CSS2/visuren.html#block-formatting section 9.4.1 –

Solution 2

 div.left {
     float: left;
     width: 200px;
    height:200px;
    background:red;
 }

 div.right {
    float:right;
     width: 200px;
     height:200px;
    background:blue;
}

see http://jsfiddle.net/3kUpF/

Alternatively, if you want them side by side then you can float:left on both see http://jsfiddle.net/3kUpF/1/

Solution 3

Floating elements can flow "into" block elements, occupying the same line but pushing the contents (not the element itself) over. In this case, left is "inside" right, but there isn't any space left for the text on the right, so it goes underneath. To see what I mean, try setting the width of right to 300px instead of 200px - you should see the blue border "around" left, with the text flowing around it. To "fix" this, I'd suggest giving right a float of left or a display of block-inline.

Share:
21,088

Related videos on Youtube

GateKiller
Author by

GateKiller

I am a Web Developer working in the UK, developing web applications in ASP.NET C#. Click me

Updated on July 09, 2022

Comments

  • GateKiller
    GateKiller almost 2 years

    I have two divs on a webpage and I would like both of them to have a fixed width and would like the first div to be floated to the left of the second div.

    This sounds so simple that I though the following Markup and CSS would give me the desired result:

    <div class="left">Content</div>
    <div class="right">Content</div>
    
    div.left {
        float: left;
        width: 200px;
    }
    
    div.right {
        width: 200px;
    

    This doesn't work as expected, instead the right div appears on the next line as though it wasn't floated. This is best explained in this example webpage:

    Example of the Problem

    My question is WHY this doesn't work as expected? Not how to fix it.

    Notes:

    • Please make sure you fully understand how floats work before answering this question.
    • Please make sure you view and understand the examples.
    • Both elements must be block, not inline.
    • I understand all fixes/hacks to make this work. I want to know why it doesn't work.
    • This appears to only work correctly in Opera.
    • Backing up your answer with documentation is required.
  • GateKiller
    GateKiller about 13 years
    But why? This doesn't seem to be the correct behavior... and this answer doesn't give the desired result.
  • GateKiller
    GateKiller about 13 years
    I don't want the elements to be inline.
  • Hussein
    Hussein about 13 years
    inline is really used for li's. It doesn't work well in this case. jsfiddle.net/3kUpF/2
  • Hussein
    Hussein about 13 years
    You are dealing with 2 different divs each with a different class. if it was an li inside ul, then we can do float:left once, and it will apply to all li's
  • GateKiller
    GateKiller about 13 years
    But why doesn't it work? I believe it should. Having the right element as inline is useless if I want to set a height, or add top and bottom padding.
  • gor
    gor about 13 years
    2GateKiller: because floats were designed to work with inline elements. Think about picture in text.
  • Hussein
    Hussein about 13 years
    Because when we reference li, we do ul.li , so all li's inside the ul will get the same styling properties. It will work for this case if both divs have the same class name. But in your css you have 2 class names and different properties for each
  • GateKiller
    GateKiller about 13 years
    @gor: Can you backup this claim with any documentation?
  • GateKiller
    GateKiller about 13 years
    This seems like a hack rather than a solution. If I add a P element after the right DIV, then the P element will be moved onto the same line as both DIV elements. This would require a clear float fix which isn't a good solution either.
  • Hussein
    Hussein about 13 years
    see this jsfiddle.net/3kUpF/8, if both have the same class name then we only need to define float:left once
  • GateKiller
    GateKiller about 13 years
    Sure, I totally understand this as explained in the example HTML I linked to. But if I add a paragraph jsfiddle.net/u2jmz then I would need to add extra markup to clear the float. A bad practice imo.
  • Hussein
    Hussein about 13 years
    Of course this is expected. All you need to do is p{clear:left} and this will apply to all p's. jsfiddle.net/u2jmz/3. Nothing happens by magic, this is normal procedure. You have to code the behavior you want.
  • GateKiller
    GateKiller about 13 years
    Again, this seems like a fix/hack rather than a proper solution or an explanation as the why this doesn't work as expected.
  • GateKiller
    GateKiller about 13 years
    @gor: Your updated answer is a fix but at the expense of extra markup and css.
  • gor
    gor about 13 years
    here is a good article. trying to find proper citation
  • Scott Brown
    Scott Brown about 13 years
    I think I might be misunderstanding your question. Which div do you want the furthest left, the first one or the second one? "the second div to be floated to the left of the first" makes it sound link you want the .right to be on the left.
  • GateKiller
    GateKiller about 13 years
    @gor: That article certainly explains a lot about floats but doesn't touch on this problem.
  • gnur
    gnur about 13 years
    I think that in this case your expectations are a bigger part of the problem then how this tag works. If adding 1 rule in a css file would make the <p> tag behave as you would expect it to could solve my problems I would be very happy :)
  • GateKiller
    GateKiller about 13 years
    @alex: Can you backup your claim that this is "normal"? I believe that this behavior is incorrect but if you have any documentation that proves otherwise I would be very grateful. Like I've explain before, the clear:left fix will work but shouldn't be needed.
  • GateKiller
    GateKiller about 13 years
    I would agree that my expectation could be the problem. However, why does Opera implement this the way I want and not other browsers. Who is right? Who is wrong? and why?
  • Hussein
    Hussein about 13 years
    This is the correct procedure in it's simplest form. We are not using any hacks or doing anything special. It can't get any simpler then this. Your stressing too much over it. Very basic stuff, no documentation.
  • gnur
    gnur about 13 years
    @gatekiller All browsers display elements slightly different. Even browsers that use the same engine (chrome & safari both use webkit) aren't exactly the same on every page. Unfortunately, there is no real right or wrong in the html business.
  • GateKiller
    GateKiller about 13 years
    @alex: Can you explain why Opera produces the original markup in the question how I expect it to do so and other browsers don't. I cannot find any documentation to explain why a width on a block element would cause it not to be floated.
  • Hussein
    Hussein about 13 years
    Different browsers behave differently. You have to create a markup that works on all browsers. You can't assume your code is correct because one browser displayed it properly, and then you try to find a fix for all other browsers. You need to look at all browsers in general. I provided you with more then one example to show you different ways. All of which are cross browser compatible in it's simplest form.
  • Elroy Flynn
    Elroy Flynn about 13 years
    It seems to me that it is the simple rule that blocks, unless floated, always start a new line. w3.org/TR/CSS2/visuren.html#block-formatting section 9.4.1
  • GateKiller
    GateKiller about 13 years
    Sure, but my question wasn't how do I fix this, my question was, why doesn't a block element with a width get floated when one without does?
  • GateKiller
    GateKiller about 13 years
    @Elroy Flynn Thank you very much :) This does make sense now even if it's not what I expected. If you submit that comment as an answer, I'll mark it as correct.
  • GateKiller
    GateKiller about 13 years
    @elroy-flynn Please add your comment as an answer so that I may give you some reputation :)
  • Hussein
    Hussein about 13 years
    It's a bad practice not to specify width property. You risk getting the div to display differently in different browsers. When specifying a width, you have to use the css properties i showed you.
  • GateKiller
    GateKiller about 13 years
    A span is an inline element and this problem revolves around block elements.
  • ikartik90
    ikartik90 about 13 years
    In that case you may add up a div around the spans somewhat as follows in order to dive the spans the functionality of a div: <div> <span></span> <span></span> </div> hope it helps.
  • GateKiller
    GateKiller about 13 years
    Thank you very much for this answer. I guess adding a width to a block element puts it in it's own context and thus on a new line.
  • GateKiller
    GateKiller about 13 years
    Seems like a lot of unnecessary markup. Anyway, there is now an answer as to why this happens.
  • Michael Martin-Smucker
    Michael Martin-Smucker about 13 years
    +1 for linking to documentation explaining what's going on here. Also, to solve your initial problem @GateKiller, you should set the second div to display: inline-block. This way, your content is still organized semantically and you don't need to add any hacky markup to your html (like a clearing div or wrapping things in span elements as others suggested) or to your css (like forcing all p elements to clear: both. It's the best of both worlds with the simplest possible markup: jsfiddle.net/mlms13/mmUpY
  • Michael Martin-Smucker
    Michael Martin-Smucker about 13 years
    @gor, no need for that extra br in there. You can just set #container to overflow: auto;.
  • Hussein
    Hussein about 13 years
    @GateKiller If p is after left div, this will not work as you wish jsfiddle.net/mmUpY/2. only way to do it is to clear p. and float both divs left. unless this is what you are looking for.
  • Michael Martin-Smucker
    Michael Martin-Smucker about 13 years
    @alex, if you don't want anything to be to the right of the #left div, why would you float it in the first place? ...or maybe I'm not understanding?
  • just.another.programmer
    just.another.programmer over 11 years
    If you change the @GateKiller s example so left-beta is float: right instead of float: left, it will show the two elements side by side (with a right float effect obviously). Why would the rule you quoted not apply in this case?
  • Lucke
    Lucke over 3 years
    So why if you explicited put width does not work float and if you Do not put width it does work ?

Related