What does the following CSS rule do:
.clear { clear: both; }
And why do we need to use it?
I won't be explaining how the floats work here (in detail), as this question generally focuses on Why use clear: both; OR what does clear: both; exactly do...
I'll keep this answer simple, and to the point, and will explain to you graphically why clear: both; is required or what it does...
Generally designers float the elements, left or to the right, which creates an empty space on the other side which allows other elements to take up the remaining space.
Why do they float elements?
Elements are floated when the designer needs 2 block level elements side by side. For example say we want to design a basic website which has a layout like below...
Live Example of the demo image.
Code For Demo
/* CSS: */
* { /* Not related to floats / clear both, used it for demo purpose only */
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
header, footer {
border: 5px solid #000;
height: 100px;
}
aside {
float: left;
width: 30%;
border: 5px solid #000;
height: 300px;
}
section {
float: left;
width: 70%;
border: 5px solid #000;
height: 300px;
}
.clear {
clear: both;
}
<!-- HTML -->
<header>
Header
</header>
<aside>
Aside (Floated Left)
</aside>
<section>
Content (Floated Left, Can Be Floated To Right As Well)
</section>
<!-- Clearing Floating Elements-->
<div class="clear"></div>
<footer>
Footer
</footer>
Note: You might have to add header, footer, aside, section (and other HTML5 elements) as display: block; in your stylesheet for explicitly mentioning that the elements are block level elements.
Explanation:
I have a basic layout, 1 header, 1 side bar, 1 content area and 1 footer.
No floats for header, next comes the aside tag which I'll be using for my website sidebar, so I'll be floating the element to left.
Note: By default, block level element takes up document 100% width,
but when floated left or right, it will resize according to the
content it holds.
Normal Behavior Of Block Level Element
Floated Behavior Of Block Level Element
So as you note, the left floated div leaves the space to its right unused, which will allow the div after it to shift in the remaining space.
div's will render one after the other if they are NOT floated
div will shift beside each other if floated left or right
Ok, so this is how block level elements behave when floated left or right, so now why is clear: both; required and why?
So if you note in the layout demo - in case you forgot, here it is..
I am using a class called .clear and it holds a property called clear with a value of both. So lets see why it needs both.
I've floated aside and section elements to the left, so assume a scenario, where we have a pool, where header is solid land, aside and section are floating in the pool and footer is solid land again, something like this..
So the blue water has no idea what the area of the floated elements are, they can be bigger than the pool or smaller, so here comes a common issue which troubles 90% of CSS beginners: why the background of a container element is not stretched when it holds floated elements. It's because the container element is a POOL here and the POOL has no idea how many objects are floating, or what the length or breadth of the floated elements are, so it simply won't stretch.
Normal Flow Of The Document
Sections Floated To Left
Cleared Floated Elements To Stretch Background Color Of The Container
(Refer [Clearfix] section of this answer for neat way to do this. I am using an empty div example intentionally for explanation purpose)
I've provided 3 examples above, 1st is the normal document flow where red background will just render as expected since the container doesn't hold any floated objects.
In the second example, when the object is floated to left, the container element (POOL) won't know the dimensions of the floated elements and hence it won't stretch to the floated elements height.
After using clear: both;, the container element will be stretched to its floated element dimensions.
Another reason the clear: both; is used is to prevent the element to shift up in the remaining space.
Say you want 2 elements side by side and another element below them... So you will float 2 elements to left and you want the other below them.
div Floated left resulting in section moving into remaining space
Floated div cleared so that the section tag will render below the floated divs
1st Example
2nd Example
Last but not the least, the footer tag will be rendered after floated elements as I've used the clear class before declaring my footer tags, which ensures that all the floated elements (left/right) are cleared up to that point.
Clearfix
Coming to clearfix which is related to floats. As already specified by #Elky, the way we are clearing these floats is not a clean way to do it as we are using an empty div element which is not a div element is meant for. Hence here comes the clearfix.
Think of it as a virtual element which will create an empty element for you before your parent element ends. This will self clear your wrapper element holding floated elements. This element won't exist in your DOM literally but will do the job.
To self clear any wrapper element having floated elements, we can use
.wrapper_having_floated_elements:after { /* Imaginary class name */
content: "";
clear: both;
display: table;
}
Note the :after pseudo element used by me for that class. That will create a virtual element for the wrapper element just before it closes itself. If we look in the dom you can see how it shows up in the Document tree.
So if you see, it is rendered after the floated child div where we clear the floats which is nothing but equivalent to have an empty div element with clear: both; property which we are using for this too. Now why display: table; and content is out of this answers scope but you can learn more about pseudo element here.
Note that this will also work in IE8 as IE8 supports :after pseudo.
Original Answer:
Most of the developers float their content left or right on their pages, probably divs holding logo, sidebar, content etc., these divs are floated left or right, leaving the rest of the space unused and hence if you place other containers, it will float too in the remaining space, so in order to prevent that clear: both; is used, it clears all the elements floated left or right.
Demonstration:
------------------ ----------------------------------
div1(Floated Left) Other div takes up the space here
------------------ ----------------------------------
Now what if you want to make the other div render below div1, so you'll use clear: both; so it will ensure you clear all floats, left or right
------------------
div1(Floated Left)
------------------
<div style="clear: both;"><!--This <div> acts as a separator--></div>
----------------------------------
Other div renders here now
----------------------------------
The clear property indicates that the left, right or both sides of an element can not be adjacent to earlier floated elements within the same block formatting context. Cleared elements are pushed below the corresponding floated elements. Examples:
clear: none; Element remains adjacent to floated elements
body {
font-family: monospace;
background: #EEE;
}
.float-left {
float: left;
width: 60px;
height: 60px;
background: #CEF;
}
.float-right {
float: right;
width: 60px;
height: 60px;
background: #CEF;
}
.clear-none {
clear: none;
background: #FFF;
}
<div class="float-left">float: left;</div>
<div class="float-right">float: right;</div>
<div class="clear-none">clear: none;</div>
clear: left; Element pushed below left floated elements
body {
font-family: monospace;
background: #EEE;
}
.float-left {
float: left;
width: 60px;
height: 60px;
background: #CEF;
}
.float-right {
float: right;
width: 60px;
height: 120px;
background: #CEF;
}
.clear-left {
clear: left;
background: #FFF;
}
<div class="float-left">float: left;</div>
<div class="float-right">float: right;</div>
<div class="clear-left">clear: left;</div>
clear: right; Element pushed below right floated elements
body {
font-family: monospace;
background: #EEE;
}
.float-left {
float: left;
width: 60px;
height: 120px;
background: #CEF;
}
.float-right {
float: right;
width: 60px;
height: 60px;
background: #CEF;
}
.clear-right {
clear: right;
background: #FFF;
}
<div class="float-left">float: left;</div>
<div class="float-right">float: right;</div>
<div class="clear-right">clear: right;</div>
clear: both; Element pushed below all floated elements
body {
font-family: monospace;
background: #EEE;
}
.float-left {
float: left;
width: 60px;
height: 60px;
background: #CEF;
}
.float-right {
float: right;
width: 60px;
height: 60px;
background: #CEF;
}
.clear-both {
clear: both;
background: #FFF;
}
<div class="float-left">float: left;</div>
<div class="float-right">float: right;</div>
<div class="clear-both">clear: both;</div>
clear does not affect floats outside the current block formatting context
body {
font-family: monospace;
background: #EEE;
}
.float-left {
float: left;
width: 60px;
height: 120px;
background: #CEF;
}
.inline-block {
display: inline-block;
background: #BDF;
}
.inline-block .float-left {
height: 60px;
}
.clear-both {
clear: both;
background: #FFF;
}
<div class="float-left">float: left;</div>
<div class="inline-block">
<div>display: inline-block;</div>
<div class="float-left">float: left;</div>
<div class="clear-both">clear: both;</div>
</div>
CSS float and clear
Sample Fiddle
Just try to remove clear:both property from the div with class sample and see how it follows floating divs.
Mr. Alien's answer is perfect, but anyway I don't recommend to use <div class="clear"></div> because it just a hack which makes your markup dirty. This is useless empty div in terms of bad structure and semantic, this also makes your code not flexible. In some browsers this div causes additional height and you have to add height: 0; which even worse. But real troubles begin when you want to add background or border around your floated elements - it just will collapse because web was designed badly. I do recommend to wrap floated elements into container which has clearfix CSS rule. This is hack as well, but beautiful, more flexible to use and readable for human and SEO robots.
When you want one element placed at the bottom other element you use this code in CSS.
It is used for floats.
If you float content you can float left or right... so in a common layout you might have a left nav, a content div and a footer.
To ensure the footer stays below both of these floats (if you have floated left and right) then you put the footer as clear: both.
This way it will stay below both floats.
(If you are only clearing left then you only really need to clear: left;.)
Related
I can not understand how css works, and it's annoying me. I was trying to do some basic side by side two divs and one div below them.
At first I've learned that I had to give float:left for both side by side divs. For curiosity I did'nt gave float:left for the second side by side div, and I came across this layout:
(source: imge.to)
Then I gave float:left for the second side by side div, and I came across this layout:
(source: imge.to)
Question: I didn't gave float:left for third div but it didn't act like the first screen shot. Why?
css code:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
width: 1000px;
margin-left: auto;
margin-right: auto;
}
.blog-posts {
width: 50%;
background-color: #0000ff;
float: left;
}
.other-posts {
width: 25%;
background-color: #00ff00;
float: left;
}
.author-text {
background-color: #ffff00;
}
html code:
<div class="container">
<div class="blog-posts">dend endje denjde akdlsd gsjgıdg sadsujrg spsadnajd asdnsajdd</div>
<div class="other-posts">extra dummy text</div>
<div class="author-text">author text</div>
</div>
When you use a float, you break the natural box-model behavior of the markup.
Your first floated element has a width of 50%, relative to the parent (1000px) it will take the half of the .container. The second (floated) element will take the next 250px. And here comes the good thing.
The third element, which isn't floated, is also a div, thus a block-level element (so implicitly it will take 100% of the width of its parent). If you set the background-color of your first and second element to a transparent one #0000ff00 and #00ff0000 respectively. You will see your third element is growing behind them.
This is, what I mean with "breaking the box-model". Now, to understand this beter, you could start giving a explicit width to the third element. Let's say: 90%, you will see how the yellow background will reduce itself from the right side.
If you set the width to 50% it will "jump" down, to the second line. It will be even broad as the first element, but two times height. With other words, it will try to fit in the first available space.
To avoid this, in the past, we used the clearfix hack... but since flexbox and css grids are broadly supported, we don't have to rely in floats anymore for this side-by-side layouts.
Float has their own use cases, is not that float sucked, it's just not meant for layout.
For more information on this topic you can check this great article about floats on CSS-Tricks.
Wrap the items you want side by side in another wrapper, then apply flexbox to that wrapper:
.my-flex-wrap {
display: flex;
}
Then remove all the floats. Done.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
width: 1000px;
margin-left: auto;
margin-right: auto;
}
.my-flex-wrap {
display: flex;
}
.blog-posts {
width: 50%;
background-color: #0000ff;
}
.other-posts {
width: 25%;
background-color: #00ff00;
}
.author-text {
background-color: #ffff00;
}
<div class="container">
<div class="my-flex-wrap">
<div class="blog-posts">dend endje denjde akdlsd gsjgıdg sadsujrg spsadnajd asdnsajdd</div>
<div class="other-posts">extra dummy text</div>
</div>
<div class="author-text">author text</div>
</div>
The content of hr tag flow around floating elements as if it is inline elements (even if it is actually blocks). That's what I need but unfortunately hr can't have child elements except two pseudo elements.
Take a look on this demo on JsFiddle: http://jsfiddle.net/P3KEZ/
<div id="right"></div>
<div class="divider"></div>
<hr class="divider" />
#right{
background: #ffaaaa;
width: 200px;
height: 300px;
float: right
}
.divider {
background: #4d9d4d;
height: 20px;
border: none;
position: relative;
}
.divider:after, .divider:before {
content: " ";
width: 20%;
height: 100%;
display: inline-block;
position: absolute;
background: #a2a2f2;
top: 0;
}
divider:before {
left: 0;
}
.divider:after {
right: 0;
}
What I actually want is to get element with content flow around the floating elements (like hr do) but also can have at least 3 child elements (like div can do).
So question is: how to emulate such behaviour in div? (without display: flex)
What I actually want is to get element with content flow around the floating elements (like hr do) but also can have at least 3 child elements (like div can do).
So question is: how to emulate such behaviour in div?
You want to harvest the power of the mighty overflow property … (*thunderclap*)
.divider {
/* … */
overflow:hidden;
}
Normally, a block element is layed out behind a floating element, only its inline content floats next to the floated element – but with overflow:hidden you can change that, so that a block element like div only takes the space that is left beside the floating element. (It does not actually have to be hidden – everything besides the default value visible will trigger this behavior, so you can use auto or scroll as well if those suit your actual use-case better.)
See here: http://jsfiddle.net/P3KEZ/1/
Look at my html + css code: http://jsfiddle.net/nP39E/1/
I'll explain if don't understand what I want to achieve:
I want a page with a div which floating right and takes 250px width and a div that takes width of the rest of the document.
In the left div, you can see that I have some other floating elements, and their heights are effected from the right div. You can see the first (red) row with height that align with the right bar's height and has nothing to do with the real content of its content.
I use group class in order to handle the common floating problem: .group:after { content: ""; display: table; clear: both; }
Can you tell me why it happens?
I just changed CSS for the content div from the last answer:
.content {
background: #888;
padding: 10px;
position: absolute;
right: 270px;
left: 0;
}
http://jsfiddle.net/nP39E/4/
What you think?
display: table isn't meant to be used for layouts like this, it's more useful for specific equal-height situations.
Properly floating the divs and not using the margin-right to push the left div will work:
.content {
background: #888;
padding: 10px;
float: left;
width: 250px;
}
Fiddle
You are giving margin-right:270px which is wider than the available space,So just remove that. Also you should make content float:left.
.content {
background: #888;
padding: 10px;
float:left;
}
JSFiddle : http://jsfiddle.net/ankur1990/nP39E/3/
So I'm having a problem with the last paragraph apparently not clearing and slipping into the middle of the h1 and nav. But when I put a div with a clear:both property before the paragraph it appears to work.
Bear with my fiddle, please.
I used a purple background to represent the image replacement technique that I learned from nettuts.
The clearfix part is a class named "group", the CSS is at the bottom.
Also if I remove the display:block; from h1 > a the layout breaks so a follow up question is, what elements should I float and where should I apply the clearfix.
The problem you are seeing arises because the clearing element is in the wrong place.
Consider your CSS:
h1 {
margin: 0;
float: left;
background: red;
text-indent: -9999px;
border: 1px dashed cyan;
}
nav {
height: 44px;
margin: 0;
float: right;
background: black;
border: 1px dashed cyan;
}
.group:after {
content:"x";
display:table;
clear:both;
background-color: cyan;
}
You have h1 floated left and nav floated right, and then you have your p block with your text (not floated).
The p content wraps around the two floated elements as expected unless you add the clear:both rule to p as pointed out earlier.
The clearing element has to appear in the DOM after the nav element.
In this example, you apply .group to nav, which generates content that appears after the ul block that is a child of the nav block.
The problem becomes more obvious is you set the nav height to auto and you add some borders and colors to show the edges of the various blocks.
See demo at: http://jsfiddle.net/audetwebdesign/9nGQy/
The problem can be seen as follows:
I added an x to mark the spot in your generated content for the clearing element, which appears within the nav block.
Try:
p{
clear:both;
}
It should work for you depending what the outcome is you are after.
Here is my jsFiddle
I just have 3 divs. The 2nd div is floated to the right, and 3rd div appears just below the 2nd.
In the 3rd div, I am setting margin-top property, and this property does not have any effect on the layout.
Question: Can someone explain me understanding this behavior of float?
HTML
<div class="header">
</div>
<div class="sidebar">
</div>
<div class="footer">
</div>
CSS
.header {
width: 100%;
height: 80px;
background-color: #abcdef;
}
.sidebar {
margin-top: 15px;
float: right;
width: 200px;
height: 200px;
background-color: #abcdef;
display: block;
}
.footer {
clear: both;
margin-top: 20px;
width: 100%;
height: 60px;
background-color: #000000;
}
This is not unexpected at all. The .sidebar is removed from regular flow layout by its float property, as such it doesn't take up any space anymore. The .footer has a clear rule, so it is forced underneath any floats, but that automatically puts it 215px (margin+height of the sidebar) behind the last element that is part of the flow layout. As such its margin requirement of 20px is completely satisfied, and it appears at its logical current position. You can verify this by setting the top margin to 220px instead, it will appear 5px (220-215) below the sidebar.
You can easily achieve the effect you desire by putting margin-bottom:20px on the sidebar since it will then be required to keep that distance to the footer, pushing it down.
The issue is related to the clear rule.
W3C - An element that has had clearance applied to it never
collapses its top margin with its parent block's bottom margin.
Baiscally, if you want to use clear, the general rule is to add an element between the two floated divs to ensure you can correctly space them.
The top margin of the footer div is being collapsed, http://www.w3.org/TR/CSS21/box.html#collapsing-margins
If you add margin-bottom to the sidebar instead of the top of the footer it will work.
This is caused by the fact that floated elements aren't really there with respect to margin calculations. Your .footer is below whatever unfloated elements are above it, (with a margin of 20px). This issue is caused because margins with respect to floats are calculated relative to other floats, (not all other elements).
So to get the desired effect add a margin-bottom element to .sidebar, have a meaningless float added to the .footer, or add a
<div style="clear:both"></div>
between the .footer and .sidebar