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.
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;
}
Header
Aside (Floated Left)
Note: You might have to add header, footer,
Header
Aside (Floated Left)
Explanation:
I have a basic layout, 1 header, 1 side bar, 1 content area and 1 footer.
No floats for header, next comes the
Header
Aside (Floated 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.
So as you note, the left floated
Header
Aside (Floated Left)
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
Header
Aside (Floated Left)
I've floated
Header
Aside (Floated Left)
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.
(Refer [Clearfix] section of this answer for neat way to do this. I am using an empty
Header
Aside (Floated Left)
I've provided 3 examples above, 1st is the normal document flow where .wrapper_having_floated_elements:after { /* Imaginary class name */ content: ""; clear: both; display: table; } 8 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.
1st Example
2nd Example
Last but not the least, the footer tag will be rendered after floated elements as I've used the
Header
Aside (Floated Left)
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
Header
Aside (Floated Left)
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 ------------------ ---------------------------------- div1(Floated Left) Other div takes up the space here ------------------ ---------------------------------- 6 pseudo element used by me for that ------------------ ---------------------------------- div1(Floated Left) Other div takes up the space here ------------------ ---------------------------------- 7. 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
Header
Aside (Floated Left)
Note that this will also work in IE8 as IE8 supports ------------------ ---------------------------------- div1(Floated Left) Other div takes up the space here ------------------ ---------------------------------- 6 pseudo.
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(Floated Left) ------------------ ---------------------------------- Other div renders here now ---------------------------------- 5, so you'll use clear: both; so it will ensure you clear all floats, left or right