hr clear vs div clear. Which is better? - html

This is a general question and something that dawned on me and seemed to make sense. I have seen many people use clearing divs <div class="clear" />and know this is sometimes frowned upon as it is extra markup. I recently started using <hr class="clear" /> as it seams representative of its actual purpose.
Both referencing of course: .clear{clear:both;}
I am looking to get some opinions if an hr tag makes more sense than a div to clear content

According to the HTML5 spec, the hr element represents a paragraph-level thematic break (a scene change in a story, or a transition to another topic within a section of a reference book) while the div element is a generic container for flow content that by itself does not represent anything. So I don't see any justification for choosing one over the other for containing floats.
However, there's something you should keep in mind. Read the following excerpt from Eric Meyer's article Containing Floats:
div.item {border: 1px solid; padding: 5px;}
div.item img {float: left; margin: 5px;}
div.item hr {display: block; clear: left; margin: -0.66em 0;
visibility: hidden;}
The negative top and bottom margins
have the general effect of closing up
the space that the hr occupies.
However, this effect is not precise,
and not necessarily identical across
browsers. The semi-mysterious nature
of horizontal rules makes it difficult
to predict exactly what will happen.
The effective height of the hr might
be zero, or a small positive amount,
or even a negative height
Therefore, in situations where a
precise clearing effect is needed,
authors can use a div instead of an hr
to create a clearing effect.
If this didn't make sense to you, see this fiddle and notice the space below the floated div (IE8).
That said, there are other ways to contain floats and avoid using structural hacks at the same time:
Float the container: may cause layout problems.
Use .container { overflow: auto; }: If the content exceeds the boundaries of the container, you will see a scrollbar.
Use .container { overflow: hidden; }: If the content exceeds the boundaries of the container, it will be hidden.
Clearfix: To be used when 2 and 3 fail.

The better solution is to not use any elements and use overflow:hidden with a hasLayout trigger for IE, or the clearfix.
Which clearfix method?

Both methods are old fashioned. The latest "trick" is to use overflow property for the container of float elements.
If for example you have:
<div id="wrapper">
<div class="float">text here</div>
<div class="float">text here</div>
</div>
with float class float:left then it's better to use overflow:hidden or overflow:auto than <div style="clear:both"></div> or the hr method.
Demo: http://jsfiddle.net/vALSL/
Read more here: http://www.quirksmode.org/css/clearing.html

I prefer the CSS only approach. Regarding the semantics between div and hr I am not sure I think hr makes any more sense to use than a div. The hr tag is meant to create a "paragraph-level thematic break".
http://dev.w3.org/html5/markup/hr.html
CSS only solution:
http://www.positioniseverything.net/easyclearing.html
<style type="text/css">
.clearfix:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.clearfix {display: inline-block;} /* for IE/Mac */
</style><!-- main stylesheet ends, CC with new stylesheet below... -->
<!--[if IE]>
<style type="text/css">
.clearfix {
zoom: 1; /* triggers hasLayout */
display: block; /* resets display for IE/Win */
} /* Only IE can see inside the conditional comment
and read this CSS rule. Don't ever use a normal HTML
comment inside the CC or it will close prematurely. */
</style>
<![endif]-->

Related

HTML border not affecting with float

So this is one of my CSS3 lines:
body{
width: 1500px;
border: 2px solid black;
text-align: left;
margin: 20px auto;
}
However, I have an Article in HTML, and when I write float:left on my CSS file, the border that's supposed to cover it stops right before the article starts, on the top.
Can anyone help me with this issue?
I want the border to surround everything.
Here is the clearfix snippet I use. Add this to the top of your css.
.clearfix:after {visibility: hidden; display: block; font-size: 0; content: " "; clear: both; height: 0; }
Like one of the commenters said. When you float an item, it disrupts the natural block level of the elements. What this means is, elements that are block level sit on top of each other, and elements that are inline, are well in a line.
So when you float items to the left, the parent div may collapse. To fix it, we add clearfix to the parent.
Honestly, you should post more of your code so we can see what's actually going on, but more than likely this will fix your issue.
Add clearfix class to your parent div (after adding it to your css)
What I mean is add it to whatever element your article is inside --
<div class ="clearfix">
<article> information </article>
</div>
I think this question has been answered all over SO, here is one post that will help- How do you keep parents of floated elements from collapsing?

The behavior of a div with responsive design [duplicate]

This question already has answers here:
What methods of ‘clearfix’ can I use?
(29 answers)
Closed 8 years ago.
Although elements like <div>s normally grow to fit their contents, using the float property can cause a startling problem for CSS newbies: If floated elements have non-floated parent elements, the parent will collapse.
For example:
<div>
<div style="float: left;">Div 1</div>
<div style="float: left;">Div 2</div>
</div>
The parent div in this example will not expand to contain its floated children - it will appear to have height: 0.
How do you solve this problem?
I would like to create an exhaustive list of solutions here. If you're aware of cross-browser compatibility issues, please point them out.
Solution 1
Float the parent.
<div style="float: left;">
<div style="float: left;">Div 1</div>
<div style="float: left;">Div 2</div>
</div>
Pros: Semantic code.
Cons: You may not always want the parent floated. Even if you do, do you float the parents' parent, and so on? Must you float every ancestor element?
Solution 2
Give the parent an explicit height.
<div style="height: 300px;">
<div style="float: left;">Div 1</div>
<div style="float: left;">Div 2</div>
</div>
Pros: Semantic code.
Cons: Not flexible - if the content changes or the browser is resized, the layout will break.
Solution 3
Append a "spacer" element inside the parent element, like this:
<div>
<div style="float: left;">Div 1</div>
<div style="float: left;">Div 2</div>
<div class="spacer" style="clear: both;"></div>
</div>
Pros: Straightforward to code.
Cons: Not semantic; the spacer div exists only as a layout hack.
Solution 4
Set parent to overflow: auto.
<div style="overflow: auto;">
<div style="float: left;">Div 1</div>
<div style="float: left;">Div 2</div>
</div>
Pros: Doesn't require extra div.
Cons: Seems like a hack - that's not the overflow property's stated purpose.
Comments? Other suggestions?
Solution 1:
The most reliable and unobtrusive method appears to be this:
Demo: http://jsfiddle.net/SO_AMK/wXaEH/
HTML:
<div class="clearfix">
<div style="float: left;">Div 1</div>
<div style="float: left;">Div 2</div>
</div>​
CSS:
.clearfix::after {
content: " ";
display: block;
height: 0;
clear: both;
}
​With a little CSS targeting, you don't even need to add a class to the parent DIV.
This solution is backward compatible with IE8 so you don't need to worry about older browsers failing.
Solution 2:
An adaptation of solution 1 has been suggested and is as follows:
Demo: http://jsfiddle.net/wXaEH/162/
HTML:
<div class="clearfix">
<div style="float: left;">Div 1</div>
<div style="float: left;">Div 2</div>
</div>​
CSS:
.clearfix::after {
content: " ";
display: block;
height: 0;
clear: both;
*zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML += '<div class="ie7-clear"></div>' );
}
.ie7-clear {
display: block;
clear: both;
}
This solution appears to be backward compatible to IE5.5 but is untested.
Solution 3:
It's also possible to set display: inline-block; and width: 100%; to emulate a normal block element while not collapsing.
Demo: http://jsfiddle.net/SO_AMK/ae5ey/
CSS:
.clearfix {
display: inline-block;
width: 100%;
}
This solution should be backward compatible with IE5.5 but has only been tested in IE6.
I usually use the overflow: auto trick; although that's not, strictly speaking, the intended use for overflow, it is kinda related - enough to make it easy to remember, certainly. The meaning of float: left itself has been extended for various uses more significantly than overflow is in this example, IMO.
Rather than putting overflow:auto on the parent, put overflow:hidden
The first CSS I write for any webpage is always:
div {
overflow:hidden;
}
Then I never have to worry about it.
The problem happens when a floated element is within a container box, that element does not automatically force the container’s height adjust to the floated element. When an element is floated, its parent no longer contains it because the float is removed from the flow. You can use 2 methods to fix it:
{ clear: both; }
clearfix
Once you understand what is happening, use the method below to “clearfix” it.
.clearfix:after {
content: ".";
display: block;
clear: both;
visibility: hidden;
line-height: 0;
height: 0;
}
.clearfix {
display: inline-block;
}
html[xmlns] .clearfix {
display: block;
}
* html .clearfix {
height: 1%;
}
Demonstration :)
There are several versions of the clearfix, with Nicolas Gallagher and Thierry Koblentz as key authors.
If you want support for older browsers, it's best to use this clearfix :
.clearfix:before, .clearfix:after {
content: "";
display: table;
}
.clearfix:after {
clear: both;
}
.clearfix {
*zoom: 1;
}
In SCSS, you should use the following technique :
%clearfix {
&:before, &:after {
content:" ";
display:table;
}
&:after {
clear:both;
}
& {
*zoom:1;
}
}
#clearfixedelement {
#extend %clearfix;
}
If you don't care about support for older browsers, there's a shorter version :
.clearfix:after {
content:"";
display:table;
clear:both;
}
Although the code isn't perfectly semantic, I think it's more straightforward to have what I call a "clearing div" at the bottom of every container with floats in it. In fact, I've included the following style rule in my reset block for every project:
.clear
{
clear: both;
}
If you're styling for IE6 (god help you), you might want to give this rule a 0px line-height and height as well.
The ideal solution would be to use inline-block for the columns instead of floating. I think the browser support is pretty good if you follow (a) apply inline-block only to elements that are normally inline (eg span); and (b) add -moz-inline-box for Firefox.
Check your page in FF2 as well because I had a ton of problems when nesting certain elements (surprisingly, this is the one case where IE performs much better than FF).
Strange no one has come up with a complete answer for this yet, ah well here it is.
Solution one: clear: both
Adding a block element with the style clear:both; onto it will clear the floats past that point and stop the parent of that element from collapsing. http://jsfiddle.net/TVD2X/1/
Pros: Allows you to clear an element and elements you add below will not be effected by the floated elements above and valid css.
Cons: Requires the another tag to clear the floats, bloating markup.
Note: To fall back to IE6 and for it to work on abstinent parents (i.e. the input element) you are not able to use :after.
Solution two: display: table
Adding display:table; to the parent to make it shrug off the floats and display with the correct height. http://jsfiddle.net/h9GAZ/1/
Pros: No extra markup and is a lot neater. Works in IE6+
Cons: Requires invalid css to make sure everything plays nice in IE6 and 7.
Note: The IE6 and 7 width auto is used to prevent the width being 100%+padding, which is not the case in newer browsers.
A note on the other "solutions"
These fixes work back to the lowest supported browser, over 1% usage globally (IE6), which means using :after does not cut it.
Overflow hidden does show the content but does not prevent the element from collapsing and so does not answer the question. Using an inline block can have buggy results, children having strange margins and so on, table is much better.
Setting the height does "prevent" the collapse but it is not a proper fix.
Invalid css
Invalid css never hurt anyone, in fact, it is now the norm. Using browser prefixes is just as invalid as using browser specific hacks and doesn't impact the end user what so ever.
In conclusion
I use both of the above solutions to make elements react correctly and play nicely with each other, I implore you to do the same.
I use 2 and 4 where applicable (i.e. when I know the content's height or if overflowing doesn't harm). Anywhere else, I go with solution 3. By the way, your first solution has no advantage over 3 (that I can spot) because it isn't any more semantic since it uses the same dummy element.
By the way, I wouldn't be concerned about the fourth solution being a hack. Hacks in CSS would only be harmful if their underlying behaviour is subject to reinterpretation or other change. This way, your hack wouldn't be guaranteed to work. However in this case, your hack relies on the exact behaviour that overflow: auto is meant to have. No harm in hitching a free ride.
My favourite method is using a clearfix class for parent element
.clearfix:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.clearfix {
display: inline-block;
}
* html .clearfix {
height: 1%;
}
.clearfix {
display: block;
}
One of the most well known solutions is a variation of your solution number 3 that uses a pseudo element instead of a non-semantic html element.
It goes something like this...
.cf:after {
content: " ";
display: block;
visibility: hidden;
height: 0;
clear: both;
}
You place that in your stylesheet, and all you need is to add the class 'cf' to the element containing the floats.
What I use is another variation which comes from Nicolas Gallagher.
It does the same thing, but it's shorter, looks neater, and maybe used to accomplish another thing that's pretty useful - preventing the child elements' margins from collapsing with it's parents' (but for that you do need something else - read more about it here http://nicolasgallagher.com/micro-clearfix-hack/ ).
.cf:after {
content: " ";
display: table;
clear: float;
}
add this in the parent div at the bottom
<div style="clear:both"></div>
The main problem you may find with changing overflow to auto or hidden is that everything can become scrollable with the middle mouse buttom and a user can mess up the entire site layout.
Another possible solution which I think is more semantically correct is to change the floated inner elements to be 'display: inline'. This example and what I was working on when I came across this page both use floated divs in much exactly the same way that a span would be used. Instead of using divs, switch to span, or if you are using another element which is by default 'display: block' instead of 'display: inline' then change it to be 'display: inline'. I believe this is the 100% semantically correct solution.
Solution 1, floating the parent, is essentially to change the entire document to be floated.
Solution 2, setting an explicit height, is like drawing a box and saying I want to put a picture here, i.e. use this if you are doing an img tag.
Solution 3, adding a spacer to clear float, is like adding an extra line below your content and will mess with surrounding elements too. If you use this approach you probably want to set the div to be height: 0px.
Solution 4, overflow: auto, is acknowledging that you don't know how to lay out the document and you are admitting that you don't know what to do.
I believe that best way is to set clear:both to the upcoming element.
Here's why:
1) :after selector is not supported in IE6/7 and buggy in FF3, however,
if you care only about IE8+ and FF3.5+ clearing with :after is probably best for you...
2) overflow is supposed to do something else so this hack isn't reliable enough.
Note to author: there is nothing hacky on clearing... Clearing means to skip the floating fields. CLEAR is with us since HTML3 (who knows, maybe even longer) http://www.w3.org/MarkUp/html3/deflists.html , maybe they should chose a bit different name like page: new, but thats just a detail...

overflow:auto adding scrollbars in Chrome, IE

I used to add a <div style='clear:both'></div> to clear floats from previous segments, but someone suggested I should use overflow:auto on the <div> with floats instead as it's simpler and more clean.
Problem is, I got reports that there were some strange 'shades' in my website. After investigating, it turns out it happens in Chrome, not in Firefox, and those 'shades' are actually very small scrollbars.
I tried to reduce the parts to a minimum in this jsfiddle http://jsfiddle.net/57HM3/4/ . note they are far to the right (by where it says 'Result'). It seems to have to do with the line-height, if I set it to 1.2 instead of 1.1 it disappears. Is this some sort of known issue (that I don't know about)?
I know there are other ways to clear them but they involve IE specific codes and what not. I'd like to keep it as it is, just making the div with the floats as overflow:auto (and if this doesn't work, I'd rather go back to my adding the extra <div>
add overflow:hidden instead of. This will clear your both and will not add any scroll
Don't monkey with overflow. I'd recommend a "clearfix" solution. Here's what I use, I put it at the top of all my style-sheets from the beginning of each project:
/* CLEAR-FIX */
.clearfix:after {
visibility: hidden; display: block; font-size: 0;
content: " "; clear: both; height: 0;
}
*:first-child+html .clearfix { zoom: 1; } /* IE7 */
...got that off a blog so long ago I can't remember where.
Any container that needs to grow with floats just needs the "clearfix" class added:
<div class="test" class="clearfix">
<div style="float:left">Hello</div>
<div style="float:left">World</div>
</div>
BTW, if you're wondering why CSS is such that floats aren't normally counted as part of a parent's height, see: Why do non-floating parents of floating elements collapse?
If you want to keep the overflow:auto rule for the container div, you can try removing the line-height rule from the .test class.

CSS clearfix how to over come the inability to center an element using it

Ok I am remastering a site for one of my clients and for years I have been doing things a little old fashion as far as CSS goes. Ive read up on some things and found the method referred to as clearfix, and I have been wanting to give it a shot since I read about it.
Now that I am giving it a shot I am finding out my method of centering an element is not working
typically I would center it margin:0 auto; but implementing the clearfix this no longer works. So now I am looking for a means of applying the same logic but keeping clearfix in the equation. I found a couple things that would work on newer browsers but not sure if they would work on older ones and I am trying to keep this as cross browser compliant as possible without hacking things to do things to do other things. Thats one of the many reasons I am remastering the site(s) I want a nice new clean code base for them from the ground up, that is compliant.
for reference this is the method of clearfix I am using
http://www.webtoolkit.info/css-clearfix.html
*EDITED TO SHOW CODE*
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>[title here]</title>
<style type="text/css" media="all">
*{margin:0;padding:0;}
body{background-color:#3F3965;font-family:Verdana, Geneva, sans-serif;color:#000;}
#content_wrap{margin:0 auto;padding:0;width:800px;background-color:#FFF;}
#content_left{width:180px;float:left;}
#content_right{width:620px;float:left;}
.rounded{
-moz-border-radius: 10px; /* Firefox */
-webkit-border-radius: 10px; /* Safari, Chrome */
border-radius: 10px; /* CSS3 */
behavior: url(border-radius.htc);
}
.border{border:solid 2px;}
.light{border-color:#999;}
.dark{border-color:#666;}
.clr{clear:both;} /*standard clear*/
/*start clearfix*/
.clearfix:after {content: ".";display: block;clear:both;visibility:hidden;line-height:0;height:0;}
.clearfix {display:inline-block;}
html[xmlns] .clearfix {display:block;}
* html .clearfix{height:1%;}
/*end clearfix*/
</style>
</head>
<body>
<div id="content_wrap" class="clearfix rounded border dark">
<div id="content_left">left</div>
<div id="content_right">right</div>
</div>
</body>
</html>
as previously mentioned the main containing element loses its "centered" position upon applying the clearfix class to it. The whole point of the clearfix from my understanding it to take parent elements that have floating elements within it is to have the element adjust itself to the height of the largest floating element within it. Now where this works like I believe it should the margin:0 auto; on the same element via a class provided otherwise gets ignored
One method to solve the miscalculation of container height of elements having floating children is to put overflow:hidden on them. The miscalculation occurs because at the time of calculating the height of container DIV the inside layout is not ready. overflow:hidden on container DIV forces recalculation of the height after all children are rendered.
<div class="container">
<div class="child">
Lorem ipsum
</div>
<div class="child">
Lorem ipsum
</div>
<div class="child">
Lorem ipsum
</div>
.container{
overflow:hidden;
}
.child{
float:left;
width:20px;
}
This will cause problem only in palces where you have some elements absolutely or relatively positioned that is actually placed outside container, like some banners and ribbons. Otherwise this is a clean solution.
PPK has one article on it http://www.quirksmode.org/css/clearing.html
Ok, Ill answer my own question. Seeing as no one here could provide anything better or in a sense specific to the question.
What I ended up doing is taking another div placing it inside the content_wrap div, and removed the clearfix class from this element. This this new div was given the class of clearfix and wrapped around the rest of the content divs so it would apply the clearfix the way intended.
This allowed for the content_wrap div to center the way I wanted it to.
Expanding on chris's answer, you want two wrappers in this scenario.
The outside wrapper should set the width of the container, and apply your margin: 0 auto; styling:
.content_center {
width: 800px;
margin: 0 auto;
}
Then, we can apply the clearfix class and styles to your content wrapper, and set it's width to 100% (of its parent):
.content_wrap {
width: 100%;
}
Here's a fiddle.

Clearing floats without extra markup

I was reading this page here: http://robertnyman.com/2007/04/12/how-to-clear-css-floats-without-extra-markup-different-techniques-explained/ about clearing floats without extra markup but it didn't mention something I thought you could do.
Am I right in my thinking that you can also clear a float by just not floating the last element?
So if you wanted to float 3 elements, you float the first two and don't float the last one.... the last one will still float but anything after won't?
If elements in a container are set to float they will screw up.
Because the parent doesn't know the height of the floated element in it (because it isn't in the flow of the document anymore)
http://jsfiddle.net/CkdY6/
The best you can do is set the parent element to overflow: hidden
http://jsfiddle.net/CkdY6/1/
But as someone recently pointed out to me it will screw up when you want to use CSS3 stuff like a drop shadow.
http://fordinteractive.com/2009/12/goodbye-overflow-clearing-hack/
Most CSS "reset" stylesheets will have a class for auto-clearing after an element.
E.g. these rules from html5reset.org allow you to write <div class="clearfix">your floats in here</div>:
.clearfix:before, .clearfix:after { content: "\0020"; display: block; height: 0; overflow: hidden; }
.clearfix:after { clear: both; }
.clearfix { zoom: 1; }