So you think you know how clear works?
TL;DR
- Clears floating elements preceding the one it's applied to
- Whether you need
clear: left
orclear: right
depends on the direction the element is floating
I thought I understood the clear
property in CSS, but it turns out I didn’t.
Take 3 divs. Let’s float them side-by-side (excuse the pseudo-HTML):
<style>
.left {
float: left;
}
</style>
<div class="left">ALPHA</div>
<div class="left">BETA</div>
<div class="left">GAMMA</div>
They will now look something like this on the screen:
ALPHABETAGAMMA
Now let’s clear BETA:
<style>
.left {
float: left;
}
.cleared {
clear: both;
}
</style>
<div class="left">ALPHA</div>
<div class="left cleared">BETA</div>
<div class="left">GAMMA</div>
How do expect the divs to display now? Think about it for a second before scrolling down …
…
If you think that they will all be on different lines, then you’re wrong! In fact, they now look like this:
ALPHA
BETAGAMMA
Play along at home in JSBin or JSFiddle if you don’t believe me. So why is this? The answer is given in the MDN docs:
The clear CSS property specifies whether an element can be next to floating elements that precede it or must be moved down (cleared) below them. The clear property applies to both floating and non-floating elements.
See it? It’s that word precede. Applying the clear property to an element means that it doesn’t want floats in front of it. It doesn’t care if the element immediately after it floats, hence why BETA and GAMMA are adjacent. So the clear: both
is a slight red herring in that it will only apply in one direction. Using both
is like safe-guarding in case you don’t know whether your element is floating to the left or the right.
Why wouldn’t you know which side the preceding element is? Well, remember that ‘preceding’ looks different depending which direction you’re floating in: let’s float the boxes right and see what happens now:
<style>
.right {
float: right;
}
.cleared {
clear: both;
}
</style>
<div class="right">ALPHA</div>
<div class="right cleared">BETA</div>
<div class="right">GAMMA</div>
<!-- Now look like: -->
ALPHA
GAMMABETA
The order is due to the divs being floated right, and BETA still only cares about preceding elements, i.e. ALPHA. In the both examples, try changing clear:both
to clear: left
to get a clearer picture.