Understanding Bootstrap's clearfix class
Twitter BootstrapLessClearfixTwitter Bootstrap Problem Overview
.clearfix {
*zoom: 1;
&:before,
&:after {
display: table;
content: "";
// Fixes Opera/contenteditable bug:
// http://nicolasgallagher.com/micro-clearfix-hack/#comment-36952
line-height: 0;
}
&:after {
clear: both;
}
}
- Why not use
display:block
? - In addition, why does it also apply to the
::before
pseudoclass?
Twitter Bootstrap Solutions
Solution 1 - Twitter Bootstrap
.clearfix
is defined in less/mixins.less
. Right above its definition is a comment with a link to this article:
The article explains how it all works.
UPDATE: Yes, link-only answers are bad. I knew this even at the time that I posted this answer, but I didn't feel like copying and pasting was OK due to copyright, plagiarism, and what have you. However, I now feel like it's OK since I have linked to the original article. I should also mention the author's name, though, for credit: Nicolas Gallagher. Here is the meat of the article (note that "Thierry’s method" is referring to Thierry Koblentz’s “clearfix reloaded”):
> This “micro clearfix” generates pseudo-elements and sets their
> display
to table
. This creates an anonymous table-cell and a
> new block formatting context that means the :before
pseudo-element
> prevents top-margin collapse. The :after
pseudo-element is used to
> clear the floats. As a result, there is no need to hide any generated
> content and the total amount of code needed is reduced.
>
> Including the :before
selector is not necessary to clear the
> floats, but it prevents top-margins from collapsing in modern
> browsers. This has two benefits:
>
> * It ensures visual consistency with other float containment techniques that create a new block formatting context, e.g.,
> overflow:hidden
>
> * It ensures visual consistency with IE 6/7 when zoom:1
is applied.
>
> N.B.: There are circumstances in which IE 6/7 will not contain the bottom margins of floats within a new block formatting context.
> Further details can be found here: Better float containment in IE
> using CSS expressions.
>
> The use of content:" "
(note the space in the content string) avoids
> an Opera bug that creates space around clearfixed elements if the
> contenteditable
attribute is also present somewhere in the HTML.
> Thanks to Sergio Cerrutti for spotting this fix. An alternative fix is
> to use font:0/0 a
.
>
> # Legacy Firefox
>
> Firefox < 3.5 will benefit from using Thierry’s method with the
> addition of visibility:hidden
to hide the inserted character. This
> is because legacy versions of Firefox need content:"."
to avoid
> extra space appearing between the body
and its first child element,
> in certain circumstances (e.g., jsfiddle.net/necolas/K538S/.)
>
> Alternative float-containment methods that create a new block
> formatting context, such as applying overflow:hidden
or
> display:inline-block
to the container element, will also avoid this
> behaviour in legacy versions of Firefox.
Solution 2 - Twitter Bootstrap
The :before
pseudo element isn't needed for the clearfix hack itself.
It's just an additional nice feature helping to prevent margin-collapsing of the first child element. Thus the top margin of an child block element of the "clearfixed" element is guaranteed to be positioned below the top border of the clearfixed element.
display:table
is being used because display:block
doesn't do the trick. Using display:block
margins will collapse even with a :before
element.
There is one caveat: if vertical-align:baseline
is used in table cells with clearfixed <div>
elements, Firefox won't align well. Then you might prefer using display:block
despite loosing the anti-collapsing feature. In case of further interest read this article: Clearfix interfering with vertical-align.
Solution 3 - Twitter Bootstrap
When a clearfix is used in a parent container, it automatically wraps around all the child elements.
It is usually used after floating elements to clear the float layout.
When float layout is used, it will horizontally align the child elements. Clearfix clears this behaviour.
Example - Bootstrap Panels
In bootstrap, when the class panel is used, there are 3 child types: panel-header, panel-body, panel-footer. All of which have display:block layout but panel-body has a clearfix pre-applied. panel-body is a main container type whereas panel-header & panel-footer isn't intended to be a container, it is just intended to hold some basic text.
If floating elements are added, the parent container does not get wrapped around those elements because the height of floating elements is not inherited by the parent container.
So for panel-header & panel-footer, clearfix is needed to clear the float layout of elements: Clearfix class gives a visual appearance that the height of the parent container has been increased to accommodate all of its child elements.
<div class="container">
<div class="panel panel-default">
<div class="panel-footer">
<div class="col-xs-6">
<input type="button" class="btn btn-primary" value="Button1">
<input type="button" class="btn btn-primary" value="Button2">
<input type="button" class="btn btn-primary" value="Button3">
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-footer">
<div class="col-xs-6">
<input type="button" class="btn btn-primary" value="Button1">
<input type="button" class="btn btn-primary" value="Button2">
<input type="button" class="btn btn-primary" value="Button3">
</div>
<div class="clearfix"/>
</div>
</div>
</div>