Why the 'float' css attribute influence parent sibling div? - html

I've this simple html code, I want to know why the parent sibling div is influenced by the float css arrtibute. Is float is relative to the window not the block the element with float arrti in?
.floatLeft {
float:left;
}
<div >
<img class="floatLeft" src="https://i.stack.imgur.com/xdrQi.jpg?s=48&g=1"/>
<p>test</p>
</div>
<div>
<p>test1</p>
</div>

That's because the parent element collapses. See The great collapse.
The reason this happens, is because otherwise there would be virtually no way to wrap your text around your image. So the parent collapses to the minimum height required for its non-floated contents, and the next div just moves up, with its contents also respecting the float of the image. This way, you can easily create these kinds of text layouts, which would otherwise be hardly possible.
If you don't want this for whatever reason, you can clear the second div, so it doesn't float next to the image, there are multiple ways to do that, but a common one is to use a pseudo-element as a 'clearfix' element. The advantage of this solution is that you don't need any additional markup, apart from maybe an id or class to identify the element to be cleared.
In the example below, I just added a snippet of CSS which finds the first div, and styles the ::after pseudo-element so it is like you insert a cleared element after the contents of the first div.
This will force the first div to grow to below the image, and so the second div is forced fown.
You could add a class to the first div to select it, but for the sake of argument, I used the selector div:first-child::after, so I could leave the mark-up of your example completely untouched:
.floatLeft {
float:left;
}
div:first-child::after {
content: "";
display: block;
clear: both;
}
<div >
<img class="floatLeft" src="https://i.stack.imgur.com/xdrQi.jpg?s=48&g=1"/>
<p>test</p>
</div>
<div>
<p>test1</p>
</div>
For more information on the subjects of floats, including various ways to do the clear fix, see the excellent All about floats on CSS-tricks.com.

.floatLeft {
float:left;
}
.clear:after {
content: '';
display: block;
clear: both;
}
<div class="clear">
<img class="floatLeft" src="https://i.stack.imgur.com/xdrQi.jpg?s=48&g=1"/>
<p>test</p>
</div>
<div>
<p>test1</p>
</div>

Related

Why the only child element of inline container could still have line break?

This is the code I am referring to.
<div id="left" style="display: inline;">1</div>
<div id="right" style="display: inline;">
<div id="inner">2</div>
</div>
I noticed the #inner div element would still have line break, so that put #right and #inner underneath #left.
I was expecting #left, #right and #inner all at the same line, since I marked both #left and #right as inline. It seems #inner could see to its parent layers, that there is the #left element next to it, even though #inner is really inside #right.
Why is browser behaving like this? Shouldn't the browser separate the scope, and make #inner not see the outside world?
The #inner div is still displayed as a block. By default, blocks take an entire line to themselves. In essence, the #inner div is making its inline parent stretch until it "comes" to the left and right edges of the latter's container. This behavior is expected.
Instead of setting display of #left and #right as inline, set it as inline-block. This declaration will make these divs wrap around the content of their children.
Here's the fiddle that shows that: http://jsfiddle.net/22Zvs/.
body > div {
display: inline-block;
}
"Why is browser behaving like this?"
Because the inner div element is still a block element, so by default it starts on a new line.
Rather than specifying the display:inline style with an inline style="" attribute, give those elements a class:
<div id="left" class="inline">1</div>
<div id="right" class="inline">
<div id="inner">2</div>
</div>
...and then in your stylesheet define both elements with that class and div elements that are descendants of that class as being inline:
.inline, .inline div { display: inline; }
Demo: http://jsfiddle.net/k4CCs/
Or of course if you just want every div on the page to be inline you don't need the class or style attributes, you can just do this in your stylesheet:
div { display: inline; }
This is happening because #inner inherits the base div style of display: block; that all divs have. This style is from the User Agent Stylesheet generated by your browser when it interprets your website ( The interpretation can be different between browsers ) . So although its parent is using display inline, is not inherited by the child element. You can confirm this by using dev tools and inspecting the element to see this base style:
div {
display: block;
}
The parent div essentially molds to shape of the child, thus giving you that line break.
Solution if you want it:
You can use a separate style sheet and use display: inline; like so:
css:
div {display: inline;}
html:
<div id="left">1</div>
<div id="right">
<div id="inner">2</div>
</div>
if you dont want to include an external style sheet you can include it in the head tag:
<head>
<style>
div {display: inline;}
</style>
</head>
example in a fiddle: http://jsfiddle.net/LW7Ly/

Why doesn't the height of a container element increase if it contains floated elements?

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;
}

Vertically centering multiple div's in its parent div

I have a set of elements inside a parent element. The parent element's height can change (it will be changed by some jQuery files). Here is how the layout looks:
<div class = "parent">
<div class="child1">
</div>
<div class="child2">
</div>
</div>
I want the child elements to end up aligned at the middle of the parent div, but i can't figure out how to write the css to do so. I have tried writing things like:
.child1 {
...
vertical-align: middle;
}
Which doesn't work. I have also tried:
.parent {
display:table;
}
.child1 {
display:table-cell;
vertical-align:middle;
}
This also doesn't work. Any ideas how to do this?
You can create a wrapper for the elements you wish to center inside a container that gets centered instead like so:
HTML
<div class ="parent">
<div class="centerme">
<div class="child1">
....
</div>
<div class="child2">
....
</div>
</div>
</div>
Then you can simply do this:
CSS
.block:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
margin-right: -0.25em; /* Adjusts for spacing */
}
Demo. Method found over at CSS-tricks.
Check this link : http://www.jakpsatweb.cz/css/css-vertical-center-solution.html
this will bring your child div's top to 50% of the container. just add margin-top: -(x)px; where (x) is half of your child div's height.
You have forgotten to apply the same styling on child2 as on child1, like so:
.child1, .child2 {
display:table-cell;
vertical-align:middle;
}
Here is a jsfiddle: http://jsfiddle.net/D853q/1/
This is slightly more complicated than your standard "how do I vertically align a single div inside a parent container."
If you have a multiple number (which can change) of child elements that need to be aligned vertically or if your parent container's height changes, then you will need to use Javsacript/JQuery to set the position as there is no "standard" way to apply a middle vertical alignment to multiple child elements inside a parent container utilizing just CSS.
EDIT: I've been proven wrong, you can apparently with using :before pseudo-element, but it won't work in IE7 unless you hack around it.
I've implemented this in a fiddle: http://jsfiddle.net/rJJah/20/
Key parts
Each Child element has a position:relative. This is important because certain child elements may have variable height, and this eliminates the need to calculate the top position separately for each.
Everytime you change the height of the parent container, you will need to rerun the height calculations and setting the top offset to each child.

Grow height of parent div that contains floating nested divs

I can’t seem to auto-grow my parent div’s height based on its floating child divs. All the children are floating, to take up space horizontally, and then wrapping to the next line. There can be a changing number of floating children, and the parent has to auto-size its height. (The parent div serves as a background for all the floating divs). There is also a second div below the parent div that needs to be pushed down, so that it is below the floating divs.
It’s of major importance that the solution works in IE.
If the parent container only has floating children, it will have no height. Adding the following CSS to the parent container should help:
.parent {
overflow:hidden;
width: 100%;
}
Read this article for more: http://www.quirksmode.org/css/clearing.html.
You could insert a div that clears the floaters after the last child.
HTML:
<div style="clear: both"></div> <!-- This goes after the last floated element - no floating elements are allowed on either side of this. -->
fiddle: http://jsfiddle.net/Rc5J8/
You need to clear floated elements the height of their parents will collapse.
The current accepted answer is correct, however it's usually a better idea to clear floats by applying the clearfix hack or overflow: hidden to a wrapping parent element so that margins continue to functions as expected, and to get rid of an empty HTML element.
The overflow-method:
CSS:
.wrap { overflow: hidden }
.box { float: left; }
Markup:
<div class="wrap">
<div class="box">
Content
</div>
<div class="box">
Content
</div>
</div>
The clearfix-method, as linked above:
CSS:
.cf:before,
.cf:after {
content: " ";
display: table;
}
.cf:after { clear: both; }
.cf { *zoom: 1; }
.box { float: left; }
Markup:
<div class="wrap cf">
<div class="box">
Content
</div>
<div class="box">
Content
</div>
</div>
You should use the clearfix technique on the containing div
http://www.webtoolkit.info/css-clearfix.html
That removes the need to add extra markup.
Adding the overflow css property on the parent element will fix the issue (no need for an empty & ugly div element to clear the float) :
.parentelement {
overflow:auto;
display: block;
width: 100%;
}
I added the display and width properties because some browsers will need theses properties to be defined.
You need to apply clearfix to the parent as floats are removed from the flow of the document an don't automatically add any height to the parent's contents. Clearfix instructs teh parent to extend to a height tall enough to clear its last floated child. This method is well established and works across browsers.

Possible to create an inline-block that isn't actually inline?

I often find that I want an element to adjust its width to the size of the elements it contains. inline-block acheives this. However, I do NOT want the inline part of inline-block -- i.e., I still want the next inline-block element to appear below it.
Is there a simple way to achieve this in CSS? I know I can't always but <br> tags after the element in my HTML, but that's annoying.
You can do that with two elements:
<div>
<div class="element">
content...
</div>
</div>
With the CSS rule:
.element { display: inline-block; }
Treat .element as the "real" element that you're adjusting the width of. The enclosing <div> is just there to force each element into its own inline flow.
there are many solutions, the most common one is to use float
<div class="float">
<div class="child">here is content</div>
</div>
.float{float: left;}
if you want enforce that an element is in the new line you add clear: both (or left or right, depending on your needs)
please take into account, that display: inline-block does not work in IE7. The only problem with float is when you want this div to adjust to the width of a child AND to position it at the middle of the page horizontaly
one more note, remember that overflow: hidden property is your best friend whenever you encounter any issues with floated divs :)
Here is a fiddle that achieves what you describe: http://jsfiddle.net/PhilippeVay/VwCgJ/
It uses floating elements (thus width is ajusted to content), a class on the last element you want on a line and the clear property on the next element, with the help of the adjacent selector .rightmost + span
HTML:
<p>
<span>lorem</span>
<span class="rightmost">ipsum</span>
<span>third item: below please</span>
<span>fourth and last</span>
</p>
CSS:
span {
display: block;
float: left;
padding: 20px;
background: lightblue;
border-right: 2px solid white;
}
.rightmost {
background: red;
color: white;
}
.rightmost + span {
clear: both;
}
Inline content (as for inline-block) will occupy the whole width of its container and you've to force a new line with the br element.
On the other side, floating elements can be cleared (and with adjacent selector, you can clear the element after a particular one).