css clearfix affected by siblings - html

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>

Related

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

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>

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.

Child padding falls outside the parent element

Applying padding to child elements is making the child draw over the boundaries of its containing parent. Can you please explain the size consideration in margin, padding and content width.
If we increase the padding why don't the parent also resize to the accumulative size of all the children considering the child's padding also?
http://jsfiddle.net/NkXUW/4/
<div>
<ul>
<li><a>srikanth</a>
</li>
<li><a>sunkist</a>
</li>
<li><a>sunday</a>
</li>
</ul>
</div>
div {
margin-top:90px;
margin-left:90px;
background-color:#676896;
}
ul {
list-style-type:none;
}
ul li {
display:inline-block;
}
a {
background-color:#c34567;
padding:10px 10px 10px 10px;
}
What are coding practices that we need to consider to over come this problem.?
Ok guys I got lot answers that do work. Can anybody explain the parent size calculation based on child elements. what are characteristics of the child that are considered while calculating the encompassing parent's size. when the whole padding is considered when it not considered ?
the reason the child was overdrawing the boundaries of the parent is because the child is a tag of type <a> which by default is display:inline (you can see if that you go in chrome developer tools and see under computed style). an inline element displays like a line of text.. so the way it treats width and height and all that is very different than a block (a div for example is a block by default).
that being said, if you change the display setting of a to display:inline-block you get to keep the inline properties of <a> but at the same time also get the block properties, namely having a padding and width and height that is recognised by its parent node, which will then expand to accommodate it.
So there aren't any best practices about this. The only best practice is to understand what each display property mean (ie inline vs block vs inline-block) and put it to its proper use.
Use display:inline-block;
a {
background-color: #C34567;
display: inline-block;
padding: 10px;
}
SEE DEMO
An inline element has no line break before or after it, and it tolerates HTML elements next to it.
A block element has some whitespace above and below it and does not tolerate any HTML elements next to it.
An inline-block element is placed as an inline element (on the same line as adjacent content), but it behaves as a block element.
http://www.w3schools.com/cssref/pr_class_display.asp
Can be solved without making any change in a tag. Just add overflow: hidden; property to div element.
div {
margin-top:90px;
margin-left:90px;
background-color:#676896;
overflow: hidden; /*expends its height if not fixed*/
}
Updated fiddle here: http://jsfiddle.net/NkXUW/52/
You must do add display: block; to <a> element to expand parent as you need.
See this fiddle
about different between margin and padding please read this maybe it help you
I don't think this is correct float your div wrapper
working demo
div {
float:left;
margin-top:90px;
margin-left:90px;
background-color:#676896;
}
hope this help you..

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

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.

How to avoid empty clear divs?

I have been using a lot of floats recently like this:
<div id="buttons">
<input type="button" id="btn1" value="Button One">
<input type="button" id="btn2" value="Button Two">
<input type="button" id="btn3" value="Button Three">
</div>
Sometimes I'll float a button to the right. Sometimes I'll float all of them to the right. This is where the problem starts. It really throws the flow off if I do that so I have to keep putting in these:
<div style="clear:both;"></div>
at the end. That throws off the layout if I'm not floating them all.
Is there a good solution to this?
Yes, use overflow: hidden on the container ie:
<style type="text/css">
#buttons { overflow: hidden; }
</style>
This is a big part of the CSS learning curve. When you float items, their containing element no longer takes the vertical height of the floated elements into account. There are a couple of solutions you could use to get around your dilemma.
Simply specify a hight for your #button container to the hight of your buttons:
#button { height: 30px; }
A fancier solution would be the clearfix hack. It's pretty bullet proof and will also do the trick without the need to add the extra markup and inline CSS.
#buttons:after {
content: ".";
display: block;
clear: both;
visibility: hidden;
line-height: 0;
height: 0;
}
#buttons {
display: inline-block;
}
html[xmlns] #buttons {
display: block;
}
* html #buttons {
height: 1%;
}
As long as you define the overflow of the parent, it will clear all floats.
Use overflow:auto on the parent, and your good to go!
http://www.sitepoint.com/blogs/2005/02/26/simple-clearing-of-floats/
(I have heard this works using display:inherit as well, but have not tried.)
When you float items with CSS, they're removed from the natural flow state of the page.
If they're in a container DIV, that will shift the item out and have its parent not see where the child elements have gone. The container would then shrink back to boxing as much of the area as if the elements were not even there in the first place.
In order to cover for that, you have to specify overflow:hidden for the property of the container.
By default, it is set to visible and will allow anything to just "fall out" of the box if it has been floated as such.
Correct it by setting this in your CSS:
#buttons
{
overflow:hidden;
}
This will now constrain the floating elements to show within the context and confines of the parent DIV.
Usually, the best options are the clearfix method or the method of setting 'overflow: hidden' on the containing parent.
In your specific example you do have another option: you could not float any of the inputs at all, and set 'text-align: right' on #buttons
#buttons {
text-align: right;
}
While I rely on 'overflow: hidden' quite a bit, it is worth noting that if you're trying to position any elements outside (or partially outside) of the containing element that has 'overflow: hidden' set on it, the positioned elements will be clipped off at the boundary of the containing element. (this doesn't come up too often, but is a "gotcha" to look out for.)
You might also find the blog post "Lessons Learned Concerning the Clearfix CSS Hack" by Jeff Starr interesting.