Properly clear floating elements - html

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.

Related

What's the logic behind the "new block formatting context" solution to the "I want to these floats to be wrapped by their parent" pattern?

I've been having a really hard time figuring out exactly what a Block Formatting Context is.
I've read the CSS specs but it just doesn't make sense to me.
So if given this classic problem
.container {
background-color: green;
border: solid 1px black;
}
.container div {
float: left;
width: 20%;
background-color: lightgreen;
}
<body>
<div class="container">
<div>Sibling</div>
<div>Sibling</div>
</div>
</body>
I've learned to solve it by creating a new Block Formatting Context within .container. This way, the .container div will expand and wrap the siblings floated elements.
.container {
background-color: green;
border: solid 1px black;
overflow: hidden;
}
.container div {
float: left;
width: 20%;
background-color: lightgreen;
}
<body>
<div class="container">
<div>Sibling</div>
<div>Sibling</div>
</div>
</body>
My understanding would be the following :
The root element of my html document (here <body>) creates a root block formatting context.
All subsequent positionned boxes participate in this root block formatting context (given they are not floated or absolutely positionned) and are hereby positionned accordingly to the Block Formatting Context Rules.
This is the normal flow positioning.
Adding float:left to my siblings elements get them out of the normal flow and act accordingly to other rules defined in the float property section of the specs.
Then, adding overflow:hidden to my .container div creates a new block formatting context that wraps the float. Because when a block box establishes a new Block Formatting Context it becomes the reference to which the children are positioned.
Now, this is my question :
Why are the float gotten out of the root block formatting context but are wrapped in my .container block formatting context? Why aren't they out of the flow entirely?
What's the difference between the root block formatting context and the new block formatting context established by the .container div?
The phrase "a box's containing block" means "the containing block in which the box lives," not the one it generates. Visual Formatting Model w3.org
In other words, the floated divs shown have a containing block of the .container div element, and inside of that block, they have been removed from the normal flow.
The next part is a little trickier, and I am not sure why this was done, but here is what was done. Although a div without a width definition can never overflow (it's width will always be 100% of its content width), using overflow:hidden when there is a float involved has some silent implications.
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. - Floats w3.org
The result of the "must not overlap" rule here is that the containing box will have to have its height adjusted in an edge case of a "block-level, non-replaced element in the normal flow".
In addition, if the element has any floating descendants whose bottom margin edge is below the element's bottom content edge, then the height is increased to include those edges. Only floats that participate in this block formatting context are taken into account, e.g., floats inside absolutely positioned descendants or other floats are not. - 'Auto' heights for block formatting context roots w3.org
Based on that, the height of the .container div is extended to cover the floated nested div elements and exhibits the difference you are seeing.

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..

Image goes beyond container div bounds

Can someone take a look at the following fiddle: http://jsfiddle.net/R4bCy/1/
I thought that a div should adjust it's height in order to accommodate it's elements, unless the elements are positioned absolutely.
Why does the div not expand to the full height of the image?
I need to the image to be aligned to the right. The only ways that I know how to do this is align='right', position:absolute; right: 0; and float:right, all of which make the containing div not adjust it's height to the image height.
.intro {
margin: 10px;
outline: 1px solid #CCC;
background: #A00;
color: #FFF;
height:auto;
overflow:auto;
}
​.img{
float:right;
height:auto;
}​
<div class="intro">
<div class="img"> <img src="http://1.bp.blogspot.com/_74so2YIdYpM/TEd09Hqrm6I/AAAAAAAAApY/rwGCm5_Tawg/s1600/tall+copy.jpg" style="margin: 10px 10px; "/></div>
<p>Sorry, but the page you requested could not be found.</p>
</div>​​​​​​​​​​
DEMO
'Why does the div not expand to the full height of the image?'
Because floats will overlap with blocks, only block formatting contexts contain floats. (You can find a pretty good overview of the whole topic here: http://www.yuiblog.com/blog/2010/05/19/css-101-block-formatting-contexts/ )
On to solve the problem at hand:
The align=right will actually result in the img being float: right (the align attribute is deprecated and css should be used).
To contain the floated image in its parent div you need either have the parent div establish a block formatting context (block formatting contexts enclose nested floats) or explicitly clear the float with an additional element after the img that is styled as a clear: right.
An easy solution to create a block formatting context is to float the parent div as well, although my preferred solution in this case would be to simply set its overflow to hidden (also resulting in a block formatting context).
Check out the updated fiddle http://jsfiddle.net/R4bCy/8/.
What you need to do is add after the p tag,
<div style="clear:both;"></div>
Whoops, apologies, posted and you edited your question - the align right is floating it I believe (you should instead use float:right and a clearfix of some sort).
example: http://jsfiddle.net/R4bCy/5/
This is what I believe you want:
http://jsfiddle.net/R4bCy/6/
If you wanted the text on the left and the image floated to the right, please do this is your CSS:
http://jsfiddle.net/R4bCy/15/
You can also have two divs that have a width of 50% contained within a container div. This will allow you a little more flexibility in your placement of the image because the text and image will each have their own modifiable divs with independent attributes

Convert div to span with CSS

I have a few divs which makes a little bit too spacey between the footer and the body. So i want to convert one div to a span. But when I do that, it messes the footer's content a bit up.
How can i do this and keep the styles that already have been defined for the footer?
Thanks in advance!
Edit
div.footer {
width: 986px;
margin: 0 auto;
padding-bottom:18px;
border: 0;
text-align: left;
color:#000000;
}
As you already know, the difference between a <div> and a <span> is just that one defaults to display:block; and the other to display:inline;. To make one act as the other, just set the display style to the other type.
However, you already said you tried this and it didn't achieve the effect you were looking for. There is another display property, which is less well known, but provides a half-way house between the two:
display:inline-block;
What it does is display it inline, but still with block-like properties. (This is basically how an <img> tag works by default).
Could this be the answer you're looking for?
To convert a div to a span, simply add:
.myDiv
{
display: inline;
}
But I'm really not sure that this is the solution you're after.
Quote:
there are 2 divs next to eachother which creates a hugh gap between the body and the footerbody and the footer
Solutions:
Remove empty div(s) from HTML
Remove empty div(s) by adding display:none
Reduce height of the div(s)
Reduce margin or padding of the div(s)
Set position:relative; top:-[yourownnumber]px to .footer
Try adding overflow:auto; to your span. Also add display:block;
If there is too much space between the footer and the body, have you looked at what the margins and paddings are on the affected divs? Does something have a height or a min-height that is making some of the content within the body taller than the natural end of the content? Firebug is a great tool for this.
Div is a block element. Other block elements are paragraphs, headings, lists, etc. Span is an inline element. Other inline elements are strong, image, anchor, etc.
You still need the body to be contained in a block-level element.
How if add this:
position:relative /*optional*/
float:left;
left:0px;
I always do this before i know to use span when I first learn css I always do to my element content.

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.