W3C states that:
Since a float is not in the flow, non-positioned block boxes created before and after the float box flow vertically as if the float did not exist. However, the current and subsequent line boxes created next to the float are shortened as necessary to make room for the margin box of the float.
This work as expected with divs:
#a
{
width: 100px;
height: 100px;
background-color: blue;
float: left;
}
#b
{
width: 200px;
height: 200px;
display: block;
border: 1px solid black;
background-color: red;
}
<body>
<div id=a></div>
<div id=b></div>
</body>
Here the red div is block-level element, therefore it's ignoring the floating one. (if I changed red one to display: inline-block it would appear next to floating one)
But, if I apply display: block to an image ,it won't ignore the floating div, Why?
#a
{
width: 100px;
height: 100px;
background-color: blue;
float: left;
}
#b
{
width: 200px;
height: 200px;
display: block;
border: 1px solid black;
}
<body>
<div id=a></div>
<img id=b src="https://www.gravatar.com/avatar/5cb44dcd4ebddfea3ede8c6d46b02795?s=328&d=identicon&r=PG&f=1">
</body>
Several paragraphs after the one you quote, the spec says:
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 the margin box of any floats in the same block formatting context as the element itself.
Although you've applied display: block to your image, being an image it's a replaced element, and therefore the float cannot intrude into its bounds.
Only non-replaced block boxes that don't establish block formatting contexts and are in the same flow as a float may ignore the float.1 A block-level replaced element is not a block box, because a replaced element cannot be a block container box.2
1 You're probably thinking, that's a ridiculously specific statement, and it is. It's why terms like "block element" are considered extremely vague in CSS parlance. Then again, it doesn't help that CSS itself defines almost equally vague terms like "block box" to specifically refer to boxes that are both block-level boxes and block container boxes.
2 This does imply that "non-replaced block box" is somewhat of a tautology, which reinforces just how ridiculously specific that statement is.
W3C
These are the two things that stuck out to me when viewing the W3C. It's considering it as a line box.
A floated box is shifted to the left or right until its outer edge touches the containing block edge or the outer edge of another float. If there is a line box, the outer top of the floated box is aligned with the top of the current line box.
A line box is next to a float when there exists a vertical position that satisfies all of these four conditions: (a) at or below the top of the line box, (b) at or above the bottom of the line box, (c) below the top margin edge of the float, and (d) above the bottom margin edge of the float.
Most embarassed to be coming to others for help with this if i'm honest, but i have reached my 1 1/2 hr sanity limit.
I want to have a block (with a coloured border) postioned on the right of the page with width suitable to the text content + padding. I want it to reserve the whole row for itself without other element below creeping into the space left on the left.
I realised early on that any width = 100% would mean that the whole row would have the border rather then just the content I wanted and various experiments with float lead to the space on the left being occupied with elements creeping into the space from below. To remedy i have created a containing block with 100% width and display = block and put the border round the child div. Still doesn't work! I have the #costblock being the container and the #costs being the content:
#costsblock {
display: block;
width: 100%;
}
#costs {
border: 1px solid #008eaf;
padding: 10px 5px;
width: auto;
text-align: right;
}
<div id="costsblock">
<div id="costs">The text</div>
</div>
I have experimented with virtually all combinations of display and width and float on both the parent and the child and nothing works - I either get the whole row surrounded by the border or, if I dare to put a float: right anywhere at all then the space on the left gets filled wih elements creeping in from below.
I think that I need to contrain the child width to what is necessary to hold the text only, but I can't seem to get that working!
Your approach with the extra container element did not work, because #post is a block element, and as such still takes the whole width (unless you tell it otherwise). Anyway, there is no need for an extra element.
I want it to reserve the whole row for itself without other element below creeping into the space left on the left.
Then all you have to do is clear the float on the next element:
#costs {
float:right;
border: 1px solid #008eaf;
padding: 10px 5px;
}
#next {
clear:right;
}
<div id="costs">The text</div>
<div id="next">I am the next element following the floating one.</div>
You can use float, but be sure to have an element that has clear: both below the floating element to prevent any elements 'creeping into the space left'.
For example:
<div id="costsblock">
<div id="costs">The text</div>
<div style="clear: both"></div>
</div>
Full example: http://jsfiddle.net/thijs_s/xxc9nk1t/
You should be able do solve this by changing display to inline-block for the child and then setting text-align to right for the parent element:
#costsblock {
text-align:right;
}
#costs {
border: 1px solid #008eaf;
padding: 10px 5px;
display:inline-block;
}
It is not necessary to set display:block for a div element, since they are defined as block level elements by default.
I came across the following code on the Internet.It works but I am not getting the jist of it that is how it is working?
All div boxes get inside the container div when a dummy div with clear both property is added at the last otherwise they stay outside the container.Another thing which I got myself is that when clear was set to left it still worked ok.
HTML
<div id="main_container">
<p>Some content.</p>
<div class="floated_box"></div>
<div class="floated_box"></div>
<div class="floated_box"></div>
<div class="floated_box"></div>
<div class="floated_box"></div>
<div style="clear: both;"></div>
</div>
CSS
#main_container {
width: 400px;
margin: 20px auto;
border: 2px solid #cccccc;
padding: 5px;
}
.floated_box {
float: left;
width: 100px;
height: 100px;
border: 1px solid #990000;
margin: 10px;
}
1. We often read that a float is not in the flow. One side-effect of this behavior is that floated elements do not affect the height of their parent. Your observation that [floated elements] stay outside the container is somewhat incorrect; floated elements remain inside the container but the container's height is 0 so these elements render outside.
2. The clear property indicates that no floated element is allowed on the left, right or both sides of the cleared element. When you add a cleared element after floated elements, it is pushed below all left and/or right floated elements that appear before it to satisfy the condition. (Remember: a left-floated element allows content to flow along its right side; a right-floated element allows content to flow around its left edge; cleared content by-passes this feature).
A cleared element is still an in-flow element, when it is pushed down will will stretch the parent element along with it.
I would like to ask how height and float work. I have an outer div and an inner div that has content in it. Its height may vary depending on the content of the inner div but it seems that my inner div will overflow its outside div. What would be the proper way to do it?
<html>
<body>
<div style="margin:0 auto;width: 960px; min-height: 100px; background-color:orange">
<div style="width:500px; height:200px; background-color:black; float:right"></div>
</div>
</body>
</html>
The floated elements do not add to the height of the container element, and hence if you don't clear them, container height won't increase...
I'll show you visually:
More Explanation:
<div>
<div style="float: left;"></div>
<div style="width: 15px;"></div> <!-- This will shift
besides the top div. Why? Because of the top div
is floated left, making the
rest of the space blank -->
<div style="clear: both;"></div>
<!-- Now in order to prevent the next div from floating beside the top ones,
we use `clear: both;`. This is like a wall, so now none of the div's
will be floated after this point. The container height will now also include the
height of these floated divs -->
<div></div>
</div>
You can also add overflow: hidden; on container elements, but I would suggest you use clear: both; instead.
Also if you might like to self-clear an element you can use
.self_clear:after {
content: "";
clear: both;
display: table;
}
How Does CSS Float Work?
What is float exactly and what does it do?
The float property is misunderstood by most beginners. Well, what exactly does float do? Initially, the float property was introduced to flow text around images, which are floated left or right. Here's another explanation by #Madara Uchicha. So, is it wrong to use the float property for placing boxes side by side? The answer is no; there is no problem if you use the float property in order to set boxes side by side.
Floating an inline or block level element will make the element behave like an inline-block element.Demo
If you float an element left or right, the width of the element will be limited to the content it holds, unless width is defined explicitly ...
You cannot float an element center. This is the biggest issue I've always seen with beginners, using float: center;, which is not a valid value for the float property. float is generally used to float/move content to the very left or to the very right. There are only four valid values for float property i.e left, right, none (default) and inherit.
Parent element collapses, when it contains floated child elements, in order to prevent this, we use clear: both; property, to clear the floated elements on both the sides, which will prevent the collapsing of the parent element. For more information, you can refer my another answer here.
(Important) Think of it where we have a stack of various elements. When we use float: left; or float: right; the element moves above the stack by one. Hence the elements in the normal document flow will hide behind the floated elements because it is on stack level above the normal floated elements. (Please don't relate this to z-index as that is completely different.)
Taking a case as an example to explain how CSS floats work, assuming we need a simple 2 column layout with a header, footer, and 2 columns, so here is what the blueprint looks like...
In the above example, we will be floating only the red boxes, either you can float both to the left, or you can float on to left, and another to right as well, depends on the layout, if it's 3 columns, you may float 2 columns to left where another one to the right so depends, though in this example, we have a simplified 2 column layout so will float one to left and the other to the right.
Markup and styles for creating the layout explained further down...
<div class="main_wrap">
<header>Header</header>
<div class="wrapper clear">
<div class="floated_left">
This<br />
is<br />
just<br />
a<br />
left<br />
floated<br />
column<br />
</div>
<div class="floated_right">
This<br />
is<br />
just<br />
a<br />
right<br />
floated<br />
column<br />
</div>
</div>
<footer>Footer</footer>
</div>
* {
-moz-box-sizing: border-box; /* Just for demo purpose */
-webkkit-box-sizing: border-box; /* Just for demo purpose */
box-sizing: border-box; /* Just for demo purpose */
margin: 0;
padding: 0;
}
.main_wrap {
margin: 20px;
border: 3px solid black;
width: 520px;
}
header, footer {
height: 50px;
border: 3px solid silver;
text-align: center;
line-height: 50px;
}
.wrapper {
border: 3px solid green;
}
.floated_left {
float: left;
width: 200px;
border: 3px solid red;
}
.floated_right {
float: right;
width: 300px;
border: 3px solid red;
}
.clear:after {
clear: both;
content: "";
display: table;
}
Let's go step by step with the layout and see how float works..
First of all, we use the main wrapper element, you can just assume that it's your viewport, then we use header and assign a height of 50px so nothing fancy there. It's just a normal non floated block level element which will take up 100% horizontal space unless it's floated or we assign inline-block to it.
The first valid value for float is left so in our example, we use float: left; for .floated_left, so we intend to float a block to the left of our container element.
Column floated to the left
And yes, if you see, the parent element, which is .wrapper is collapsed, the one you see with a green border didn't expand, but it should right? Will come back to that in a while, for now, we have got a column floated to left.
Coming to the second column, lets it float this one to the right
Another column floated to the right
Here, we have a 300px wide column which we float to the right, which will sit beside the first column as it's floated to the left, and since it's floated to the left, it created empty gutter to the right, and since there was ample of space on the right, our right floated element sat perfectly beside the left one.
Still, the parent element is collapsed, well, let's fix that now. There are many ways to prevent the parent element from getting collapsed.
Add an empty block level element and use clear: both; before the parent element ends, which holds floated elements, now this one is a cheap solution to clear your floating elements which will do the job for you but, I would recommend not to use this.
Add, <div style="clear: both;"></div> before the .wrapper div ends, like
<div class="wrapper clear">
<!-- Floated columns -->
<div style="clear: both;"></div>
</div>
Demo
Well, that fixes very well, no collapsed parent anymore, but it adds unnecessary markup to the DOM, so some suggest, to use overflow: hidden; on the parent element holding floated child elements which work as intended.
Use overflow: hidden; on .wrapper
.wrapper {
border: 3px solid green;
overflow: hidden;
}
Demo
That saves us an element every time we need to clear float but as I tested various cases with this, it failed in one particular one, which uses box-shadow on the child elements.
Demo (Can't see the shadow on all 4 sides, overflow: hidden; causes this issue)
So what now? Save an element, no overflow: hidden; so go for a clear fix hack, use the below snippet in your CSS, and just as you use overflow: hidden; for the parent element, call the class below on the parent element to self-clear.
.clear:after {
clear: both;
content: "";
display: table;
}
<div class="wrapper clear">
<!-- Floated Elements -->
</div>
Demo
Here, shadow works as intended, also, it self-clears the parent element which prevents to collapse.
And lastly, we use footer after we clear the floated elements.
Demo
When is float: none; used anyways, as it is the default, so any use to declare float: none;?
Well, it depends, if you are going for a responsive design, you will use this value a lot of times, when you want your floated elements to render one below another at a certain resolution. For that float: none; property plays an important role there.
Few real-world examples of how float is useful.
The first example we already saw is to create one or more than one column layouts.
Using img floated inside p which will enable our content to flow around.
Demo (Without floating img)
Demo 2 (img floated to the left)
Using float for creating horizontal menu - Demo
Float second element as well, or use `margin`
Last but not the least, I want to explain this particular case where you float only single element to the left but you do not float the other, so what happens?
Suppose if we remove float: right; from our .floated_right class, the div will be rendered from extreme left as it isn't floated.
Demo
So in this case, either you can float the to the left as well
OR
You can use margin-left which will be equal to the size of the left floated column i.e 200px wide.
You need to add overflow:auto to your parent div for it to encompass the inner floated div:
<div style="margin:0 auto;width: 960px; min-height: 100px; background-color:orange;overflow:auto">
<div style="width:500px; height:200px; background-color:black; float:right">
</div>
</div>
jsFiddle example
You are encountering the float bug (though I'm not sure if it's technically a bug due to how many browsers exhibit this behaviour). Here is what is happening:
Under normal circumstances, assuming that no explicit height has been set, a block level element such as a div will set its height based on its content. The bottom of the parent div will extend beyond the last element. Unfortunately, floating an element stops the parent from taking the floated element into account when determining its height. This means that if your last element is floated, it will not "stretch" the parent in the same way a normal element would.
Clearing
There are two common ways to fix this. The first is to add a "clearing" element; that is, another element below the floated one that will force the parent to stretch. So add the following html as the last child:
<div style="clear:both"></div>
It shouldn't be visible, and by using clear:both, you make sure that it won't sit next to the floated element, but after it.
Overflow:
The second method, which is preferred by most people (I think) is to change the CSS of the parent element so that the overflow is anything but "visible". So setting the overflow to "hidden" will force the parent to stretch beyond the bottom of the floated child. This is only true if you haven't set a height on the parent, of course.
Like I said, the second method is preferred as it doesn't require you to go and add semantically meaningless elements to your markup, but there are times when you need the overflow to be visible, in which case adding a clearing element is more than acceptable.
Its because of the float of the div. Add overflow: hidden on the outside element.
<div style="overflow:hidden; margin:0 auto;width: 960px; min-height: 100px; background-color:orange;">
<div style="width:500px; height:200px; background-color:black; float:right">
</div>
</div>
Demo
You confuse how browsers renders the elements when there are floating elements. If one block element is floating (your inner div in your case), other block elements will ignore it because browser removes floating elements from the normal flow of the web page. Then, because the floated div has been removed from the normal flow, the outside div is filled in, like the inner div isn't there. However, inline elements (images, links, text, blackquotes) will respect the boundaries of the floating element. If you introduce text in the outside div, the text will place arround de inner div.
In other words, block elements (headers, paragraphs, divs, etc) ignore floating elements and fill in, and inline elements (images, links, text, etc) respect boundaries of floating elements.
An fiddle example here
<body>
<div style="float:right; background-color:blue;width:200px;min-height:400px;margin-right:20px">
floating element
</div>
<h1 style="background-color:red;"> this is a big header</h1>
<p style="background-color:green"> this is a parragraph with text and a big image. The text places arrounds the floating element. Because of the image is wider than space between paragrah and floating element places down the floating element. Try to make wider the viewport and see what happens :D
<img src="http://2.bp.blogspot.com/_nKxzQGcCLtQ/TBYPAJ6xM4I/AAAAAAAAAC8/lG6XemOXosU/s1600/css.png">
</p>
Try this one
.parent_div{
display: flex;
}
you can use overflow property to the container div if you don't have any div to show over the container eg:
<div class="cointainer">
<div class="one">Content One</div>
<div class="two">Content Two</div>
</div>
Here is the following css:
.container{
width:100%;/* As per your requirment */
height:auto;
float:left;
overflow:hidden;
}
.one{
width:200px;/* As per your requirment */
height:auto;
float:left;
}
.two{
width:200px;/* As per your requirment */
height:auto;
float:left;
}
-----------------------OR------------------------------
<div class="cointainer">
<div class="one">Content One</div>
<div class="two">Content Two</div>
<div class="clearfix"></div>
</div>
Here is the following css:
.container{
width:100%;/* As per your requirment */
height:auto;
float:left;
overflow:hidden;
}
.one{
width:200px;/* As per your requirment */
height:auto;
float:left;
}
.two{
width:200px;/* As per your requirment */
height:auto;
float:left;
}
.clearfix:before,
.clearfix:after{
display: table;
content: " ";
}
.clearfix:after{
clear: both;
}
OK, I'm really having problems understanding the behavior of the float property.
The page is 750 px wide. In order to keep it positioned in the center of the screen, I used this code:
<div align="center">
<div align="left" style="width:750px; border-style:double;">
stuff
</div>
</div>
The elements within the main 750 px wide container are other containers that have the following styles:
div.infoCont //these containers usualy have two more containers within- for an image and text
{
width: 740px;
position: relative;
left: 2px;
border-style: double; //for debugging
float: left;
}
div.textContNI //text only
{
width: 730px;
float: left;
clear: right;
border-style: double; //for debugging
}
The small containers behave normally (they should be, because they are positioned and as big as the way I want to). But the height of the main container is A LOT less that the total height of the smaller containers... 0 px. It ignores the height of ALL the smaller containers.
This can be "fixed" by adding text right before the closing tag of the main container. I can also manipulate the height with <br> tags and no text: the height becomes as big as the total height of the borders. Another way to "fix" the problem is to add float:left; in the style, but that positions the container on the left side of the window and I can't have that.
I'm missing something and I don't know what it is.
Why does the main container ignore the total height of the containers within it and how can I take care of this bug?
Containing floated elements
This is the correct behavior of floated elements. It's not a bug.
By default, a floated element doesn't occupy space within its parent. The same happens with elements given absolute position. The parent has two children, but they're both floated, so nothing occupies space in the parent. As a result the parent has a height of zero, unless it contains some other non-floated content.
There are three common ways to make a parent contain its floated children, so that it's at least as tall as its children.
1. Fixed height
Give the parent a fixed height that's at least as tall as the height of the floated child. Technically, the floated element still does not occupy space within the parent, but the parent is tall enough to make it appear as if it does.
.parent { height: 30px; }
.child { height: 30px; float: left; }
2. clear div
Add a trailing div with clear:both inside the parent. This forces the parent to contain the floated children. The parent automatically increases in height as needed. By default, an empty div has a height of zero in all browsers, so no additional styling is required for the trailing div.
.clear { clear: both; }
...
<div class="parent">
<!-- Floated children go here -->
...
<!-- Trailing clear div goes here -->
<div class="clear"></div>
</div>
3. clearfix
Add a clearfix rule to the CSS stylesheet, and add the class clearfix to the parent. The end result is the same as adding a clear div, but it doesn't require adding additional HTML elements. Like adding a clear div, this forces the parent to contain the floated children. The parent automatically increases in height as needed.
/* The traditional version of clearfix, a good one to start with. */
.clearfix:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.clearfix {display: inline-block;}
* html .clearfix {height: 1%;}
.clearfix {display: block;}
...
<div class="parent clearfix">
<!-- Floated children go here -->
...
</div>