Floated Child Elements: overflow:hidden or clear:both? - html

As a web developer I frequently will have two floated (child) divs inside of another (parent) div. Actually I do this all day long.
<style type="text/css">
#left {float:left;}
#right {float:right;}
</style>
<div id="parent">
<div id="left" class="child"> </div>
<div id="right" class="child"> </div>
</div>
This doesn't work without an extra bit of css/html because the parent doesn't automatically grow to fit floated children. There are two popular ways of overcoming that:
1) Add overflow:hidden to the parent's css.
2) Add a 3rd "clearing" child <br style="clear:both;" />.
I know there's a few other similar questions about such things, but my question is:
Which method is better and why? What
are the pros and cons of each?

Hidden overflow - pretty solid method. The main disadvantage is if you set a height on the parent element, any overflow will be...well, hidden. I found this when creating a menu with floated list items - the submenus would not appear.
Clearing element - rather than a line break, I would use a div with height: 0; clear: both; since it won't create a gap below. This is a more solid method, the only disadvantage being an extra element in the markup.
Float the parent - in my experience there are too many situations where you don't want to float the parent element, so I would avoid it.
You can also use the generated content method:
#parent:after {
content: ".";
visibility: hidden;
clear: both;
}
This saves the need for an extra element in the markup, but it won't work in IE7 and below.
Use inline blocks - just remembered this method. Instead of floating the two columns, set them to display: inline-block and they will appear side-by-side:
.child {
display: inline-block;
vertical-align: top;
}
Only thing you must remember with this method is if there is any whitespace between the close tag of one block and the opening tag of another, a space will appear between the columns (the size of which depends on the font so it difficult to gauge). As long as you do ...</div><div id=... then this method works fine and is superior to floating elements IMO.

The second is totally unnecessary and adds extra markup. Just something else to go wrong. Use the first if it fits the bill. You can also float the parent element to do the same thing though it might not fit what you're doing.

PPK discusses this in Clearing floats over on QuirksMode.

Related

Properly clear floating elements

I am trying to design a bar in which all elements are floating. I have no problem to do this part, but the problem is, when I try to add a new block under this one, I have either a space before my first element in this new block, or a space between my two blocks when I add clear: both;.
I already tried with new clearfix hack, but it does not work in my case.
Here is a small codepen I made, to show you the problem I have : http://codepen.io/anon/pen/piDEK. I would like to avoid to have a space between my two blocks, and my h1 should be at left (and not after my ul, you can try by removing the clear, in my codepen), obviously.
Thank you for your help.
you can clear float by giving overflow:hidden; on parent element. check the DEMO.
Like in your case use in on section element.
section{overflow:hidden;}
You could always add overflow:hidden; to #topbar (and/or #content)then remove your separate clearing div, so the revised CSS would be:
#top-bar {
width: 100%;
height: 65px;
/* border: 1px solid #e6e6e6; */
padding: 0 25px;
background: green;
overflow:hidden;
}
The purpose of overflow:hidden is not to clear floats per se, but to control child content containment by establishing a new block formatting context(BFC) flow root, one feature of BFCs is float containment.
More on BFCs from MDN
A block formatting context is a part of a visual CSS rendering of a
Web page. It is the region in which the layout of block boxes occurs
and in which floats interact with each other.
A block formatting context contains everything inside of the element
creating it that is not also inside a descendant element that creates
a new block formatting context.
Block formatting contexts are important for the positioning (see
float) and clearing (see clear) of floats. The rules for positioning
and clearing of floats apply only to things within the same block
formatting context. Floats do not affect the layout of things in other
block formatting contexts, and clear only clears past floats in the
same block formatting context.
Use clear before closeing each parent element which as floated childrens.
Use
<div class="clear"></div>
& CSS
.clear{clear:both;}
I've used this after last li, after ul & after .top-bar div.
Edit:
The white line between two divs is due to #top-bar #left-menu li element's line height is more than parents height Use,
#top-bar #left-menu li {line-height:63px;}
Here is modified codepen e.g. DEMO
Just add a display:none to the clearfix DIV's style to remove the unwanted whitespace.
<div style="clear: both; display:none"></div>
You will more than likely have more than one of these on your site so I would recommend using a class instead of inline styling.

css clearfix affected by siblings

I define a container element contains a float div and a ul,
and the ul element contains a few float li element.
I want to clear the ul's float ,but the ul's height affected by its float sibling element.
Is it a bug the clearfix has?
.clearfix {
*zoom: 1;
}
.clearfix:after {
content:".";
display:block;
height:0;
line-height: 0;
clear:both;
visibility: hidden;
}
Visit http://jsfiddle.net/ltchronus/MV9pm/ to see my demo.
The bug isn't in the clearfix, the "bug" is the clearfix.
Because the div is floating, the clearfix has to clear that floating sibling even though it's not part of the contents of the ul in the source. This is because both the ul's floating contents and the floating div participate in the same block formatting context (that of the root element).
You can easily correct this by triggering a new block formatting context in the ul by setting its overflow property to something other than visible to ensure that the clearfix is localized to just the ul's formatting context, but then once you do that the clearfix becomes completely unnecessary anyway and you may as well get rid of it altogether.
This is why I personally do not use, and do not recommend using, clearfix: at best it's an unnecessary hack — which is not to say setting overflow isn't a hack; it is, too, since triggering BFCs is but a not-so-intended side-effect and certainly not what overflow was designed to do, but it's far easier to troubleshoot than issues caused by clearfix like the one you just ran into, especially if you do not have a solid understanding of the float model (and even I don't claim that myself)
try this code
demo
<div class="container">
<div class="side-bar"></div>
<ul class="sub-container clearfix" >
<li>afjapfjapgj</li>
<li>afjapfjapgj</li>
<li>afjapfjapgj</li>
<li>afjapfjapgj</li>
</ul>
<div class="clearfix"></div>
</div>

Elements that don't take their children's width or height

I have run across this problem from time to time and have never been able to understand what causes it.
<div id="wrapper">
<div id="primary">content</div>
<div id="secondary">content</div>
</div>
#primary {
width:50%;
float: left;
}
#secondary {
width: 50%;
}
And then you look at the properties on Chrome's inspect element and the wrapper div shows up as 0px height and 0px width.
This is commonly referred to as the clearfix issue. An alternative to placing an inline-styled div below would be to assign overflow:hidden to the wrapper div.
For more information about clearing issues, check out A List Apart: CSS Floats 101 (Section 6: Collapsing specifically)
You need to add a <div style='clear:both'></div> below the <div id='secondary'/>. The CSS tag "float" does not allow the parent to see where the children actually end. Adding the div that clears the left and right sides of any floats allow the parent element to fill the space correctly.
You need to try and clear the div with the float, so try these, adding a <div> after the second div, and adding style="clear:both" to the div i just said to create as the style, or you can simply specify the exact height & width of the wrapper div, let me know what happens please. good luck!

Confusion about negative margin of float none and float left elements

I feel like CSS is much harder and confusing than C++ therefore I have few questions.
Consider following html body
<div id="mydiv1">12345~~~~~~~~/</div><div id="mydiv2">+_______67890</div>
And CSS
#mydiv1 {
float: left;
background-color: red;
margin-right: -30px;
}
#mydiv2 {
float: left;
background-color: blue;
}
which looks like this (in my latest Chrome)
which makes sense to me because second div is floating and it floats over first div.
On the other hand if I remove float property from mydiv2 only content moves but background box stays in the same place.
1) Could you please explain why ?
Now I'll remove margin and float, and add width to both divs making having CSS
#mydiv1 {
background-color: red;
width: 220px;
}
#mydiv2 {
background-color: blue;
width: 240px;
}
It will expectantly look like this
But if I add float: left to #mydiv1 it suddenly looks like this
2) Why did second div become twice as high ? I checked it by setting z-index of first div to -1.
PS. I've done tutorials on CodeAcademy and read float/margin-related articles on smashingmagazine.com. Sadly it didn't made everything crystal clear. If you guys can suggest online resources or book that would have explained these questions to me I'll appreciate it a lot.
<div> is a block-level element so it naturally fills the width of the container it's in. It makes its neighboring elements go above/below it, but not beside it.
Now, when you apply float to a block-level element, it no longer fills the width of the container, its width will be that of its contents. It also loses the ability to force its neighbors to go above/below it.
Note:The tricky bit is that the container holding the floated elements will not have a proper height because the floated elements are no longer part of the regular flow of content. (Here's how to get around it: http://www.quirksmode.org/css/clearing.html)
Regarding the last part of your question, if a floated element, eg. #mydiv1, is beside a block-level, eg. #mydiv2, then the block-level element wraps or flows around the floated element. It's one of the ways people can get text to wrap around an image in a news article.
When you remove the float from div2 it goes behind the floated div1, because floated elements does not take any height from it's content. You can say it's going out of the vertical flow of elements. However, it still take horizontal space from content. So the result is as expected here, once you "know the rules".
This should also explain the double height in your other example.
Here is a great article from css-tricks.com
I hope that helps!
If we don't give either float or width to any block level element like div then it occupies the entire width of the container.
Instead of float you can give some width and display: inline-block. This display property will display content inline and behaves like a block level element.

When should floated HTML elements be cleared exactly?

Could anyone explain when should the floated elements get cleared?
I have noticed sometimes when I make something in HTML, and I don't clear them, it still all looks good!
Also can overflow:hidden be used as a replacement for clearing?
Look at this example:
<html>
<head>
<style>
.a { background-color: red; overflow: hidden }
.floated-left { float: left; width: 100px; height: 100px; background-color: blue; }
</style>
</head>
<body>
<p>div with class a, that does have overflow:hidden:</p>
<div class="a">
<div class="floated-left">Hi,</div>
<div class="floated-left">Mom!</div>
</div>
<p>i didn't clear anything</p>
</body>
</html>
Here I didn't clear the floated divs, but set overflow:hidden for the .a class and the <p> below appeared in normal element flow.
However, if I removed overflow:hidden from the .a class, <p> gets displaced.
Please explain!
Thanks, Boda Cydo.
For block-level, non-replaced elements, when overflow isn't set to "visible" and height isn't "auto", the element's height depends on its descendents (CSS 2.1 § 10.6.6). Thus when you set overflow: hidden on .a, it stretches to contain the floated descendents. The <p> is below .a, so it's below the floats.
Without overflow: hidden, .a doesn't contain the floated children; its calculated height is 0. The <p> is still below .a, but not the floats. The floats push the inline content of <p>, as floats are wont to do.
Try putting borders around .a and paragraphs to more clearly see the difference.
overflow: hidden should be used as a replacement for clearing divs whenever it can be, which is most of the time.
IF you need to float the elements around an tire block as unit and the containing element needs to expand vertically to the height of whichever is highest. Otherwise the text/inline elements of the non-floated adjacent elements will flow around the float. If this content ends up being taller than your float then youll be ok... the container will expand. If however the floated elemnt is taller, then youll need to clear it if you want the container to be as tall as the float.
Just as I replied in your other post When should overflow:hidden be used for a <div>? this is because the child elements of the a div throw the margins out of bound for a when overflow is anything other than visible. When overflow is visible, a technically stops at the boundary of the div for "Mom!". When it is other than visible (overflow, scroll, auto), the boundary continues until it reaches the boundary of its own parent (in this case the right edge of the browser). The new block element may not begin until it has space to go in. Effective when overflow is visible, it may begin directly after the margin boundary of the last floated div. When it is other, it must wait for a full break in the div.