Why `float:left` doesn't work with a fixed width?
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.
Related videos on Youtube
GateKiller
I am a Web Developer working in the UK, developing web applications in ASP.NET C#. Click me
Updated on July 09, 2022Comments
-
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:
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 about 13 yearsBut why? This doesn't seem to be the correct behavior... and this answer doesn't give the desired result.
-
GateKiller about 13 yearsI don't want the elements to be inline.
-
Hussein about 13 yearsinline is really used for li's. It doesn't work well in this case. jsfiddle.net/3kUpF/2
-
Hussein about 13 yearsYou 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 about 13 yearsBut 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 about 13 years2GateKiller: because floats were designed to work with inline elements. Think about picture in text.
-
Hussein about 13 yearsBecause 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 about 13 years@gor: Can you backup this claim with any documentation?
-
GateKiller about 13 yearsThis 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 about 13 yearssee this jsfiddle.net/3kUpF/8, if both have the same class name then we only need to define float:left once
-
GateKiller about 13 yearsSure, 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 about 13 yearsOf 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 about 13 yearsAgain, this seems like a fix/hack rather than a proper solution or an explanation as the why this doesn't work as expected.
-
GateKiller about 13 years@gor: Your updated answer is a fix but at the expense of extra markup and css.
-
gor about 13 yearshere is a good article. trying to find proper citation
-
Scott Brown about 13 yearsI 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 about 13 years@gor: That article certainly explains a lot about floats but doesn't touch on this problem.
-
gnur about 13 yearsI 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 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 about 13 yearsI 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 about 13 yearsThis 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 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 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 about 13 yearsDifferent 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 about 13 yearsIt 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 about 13 yearsSure, 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 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 about 13 years@elroy-flynn Please add your comment as an answer so that I may give you some reputation :)
-
Hussein about 13 yearsIt'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 about 13 yearsA span is an inline element and this problem revolves around block elements.
-
ikartik90 about 13 yearsIn 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 about 13 yearsThank 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 about 13 yearsSeems like a lot of unnecessary markup. Anyway, there is now an answer as to why this happens.
-
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
todisplay: 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 inspan
elements as others suggested) or to your css (like forcing allp
elements toclear: both
. It's the best of both worlds with the simplest possible markup: jsfiddle.net/mlms13/mmUpY -
Michael Martin-Smucker about 13 years@gor, no need for that extra
br
in there. You can just set#container
tooverflow: auto;
. -
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 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 over 11 yearsIf you change the @GateKiller s example so
left-beta
isfloat: right
instead offloat: 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 over 3 yearsSo why if you explicited put width does not work float and if you Do not put width it does work ?