Clearfix на CSS

При использовании свойства float, многие новички сталкиваются с целым рядом проблем. И все они вызваны непониманием принципа работы свойства float, ведь когда мы задаем данное свойство для элемента, то он становится "плавающим" элементом и все другие элементы, которые идут за ним, начинают его обтекать.

Чтобы раз и навсегда разобраться с этой темой, я решил написать данную статью, тут я расскажу основные проблемы новичков, а также покажу решение.

Проблема #1

Родительский блок, который внутри себе содержит только лишь элементы со свойством float, "схлопывается" и фактически принимает высоту равную нулю.

Этот пример легко создать, для этого достаточно сделать родительский элемент, в нашем случае это блок с классом content и внутрь поместить два других блока, для которых заданы свойства float. В нашем случае, это блоки с классами left и right.

CSS

.content {
	width: 900px;
	margin: 20px auto;
	border: 3px solid #e34334;
}
.left {
	float: left;
	background: #15bb9a;
	width: 250px;
}
.right {
	float: right;
	background: #3f688c;
	width: 650px;
}

HTML

<div class="content">
<div class="left">Контент, который находится в левой части.</div>
<div class="right">Контент для правой части сайта, здесь находится самое главное содержимое страницы.</div>
</div>

Если посмотреть демо для данного примера, то четко видно, что родительский блок, который оборачивает два "плавающих" блока, просто "схлопнулся". Это можно понять по красной рамке, которую я специально задал для элемента с классом content.

Проблема #2

Если же в родительском блоке, помимо "плавающих" элементов есть и статические элементы к которым мы не применяли float, то высота родителя станет равной высоте этого самого статического элемента.

Этот случай аналогичен предыдущему, чтобы его увидеть, просто исправьте CSS-правило для блока right, а именно уберите свойство float (Также я еще убрал свойство width, это необходимо для того, чтобы данный блок стал иметь 100% ширину и чтобы наш пример получился более наглядным. Но в принципе, данное свойство можно и не удалять):

CSS

.right {
	background: #3f688c;
}

Если мы поглядим на демо, то действительно, высота блока-родителя стала равной высоте правого блока, как раз того самого блока, для которого мы убрали свойство float.

Проблема #3

Если после родительского блока, внутри которого находятся "плавающие" элементы, расположить еще какой-то блок, к которому мы не применяем свойство float, (на нашем примере это блок с классом line), то все равно данный блок line продолжит свою "поездку" вслед за остальными элементами.

Примечание: CSS правила в данном примере такие же, как и в первом случае.

HTML

<div class="content">
<div class="left">Контент, который находится в левой части.</div>
<div class="right">Контент для правой части сайта, здесь находится самое главное содержимое страницы.</div>
</div>
<div class="line">Какой-то элемент без свойства float</div>

Это видно в демо.

И все это неудивительно, ведь фактически, мы для блоков с классами left и right применили float. А данное свойство работает таким образом, что тот блок для которого мы задали float, уплывает влево или вправо (это зависит от того, какое значение вы указали), а все последующие элементы, которые идут за этим "плавающим" блоком начинают его обтекать с противоположной стороны.

Данное поведение, как раз и приводит к перечисленным выше проблемам.

Решение с помощью очищающего блока

Чтобы от этого избавиться, нам необходимо после "плавающих" блоков делать очищение обтекания, чтобы все последующие элементы не стали никуда "уезжать".

Самое простое и старое решение в этом вопросе - это создание дополнительного очищающего блока.

HTML

<div class="content">
<div class="left">Контент, который находится в левой части.</div>
<div class="right">Контент для правой части сайта, здесь находится самое главное содержимое страницы.</div>
<div class="clear"></div>
</div>
<div class="line">Какой-то элемент без свойства float</div>

Как видите, после наших плавающих блоков с классами left и right, мы добавили еще один блок с классом clear - это и есть очищающий блок.
Ну а для этого класса clear мы создали CSS-правило с одним единственным свойством:

CSS

.clear {
	clear: both;
}

Теперь если поглядеть демо, то у нас уже ничего не уплыло, все находится на своих местах, потому что после "плавающих" элементов мы сделали очищение потока и все последующие элементы остались на своих местах.

Данный очищающий блок вам нужно добавлять каждый раз, после элементов, к которым вы применили свойство float.

И вроде бы все хорошо, от предыдущих проблем мы избавились, но все же у данного способа есть большой недостаток. Фактически в наш HTML-каркас мы добавили какой-то непонятный, пустой элемент, который портит всю структуру и семантику кода.

Решение с помощью простого Clearfix

Поэтому верстальщики стали придумывать различные методы, которые бы избавляли от перечисленных выше проблем и при этом не требовали бы добавления дополнительных элементов в структуру HTML. Эти методы называются, как раз Clearfix.

И вот один из них, который я сам применяю на практике:

CSS

.clearfix:after {
    content: "";
    display: table;
    clear: both;
}

HTML

<div class="content clearfix">
<div class="left">Контент, который находится в левой части.</div>
<div class="right">Контент для правой части сайта, здесь находится самое главное содержимое страницы.</div>
</div>
<div class="line">Какой-то элемент без свойства float</div>

Как он работает?

Используя псевдоэлемент after, мы задаем свойство content, с помощью которого можем добавлять на нашу страницу какой-то контент. В частности, в нашем примере мы добавили элемент типа таблица и для него задали отмену обтекания.

Теперь все что нам нужно - это для родительского блока, внутри которого находятся "плавающие" элементы, задать класс clearfix.

В нашем случае, таким блоком являлся div с классом content, поэтому мы к нему добавили еще один класс с названием clearfix.

Данное решение, если посмотреть демо, также избавляет нас от перечисленных ранее проблем и при этом не требует усложнения HTML структуры.

Что касается кроссбраузерности, то данный clearfix будет отлично работать во всех современных браузерах, а также в IE8+.

Добавить комментарий

  • 01.06.2018 12:54

    Спасибо за информацию.

  • 27.06.2016 13:57

    Спасибо, это самое лучшее объяснение, которое только я нашёл.

  • 29.07.2015 11:55

    Хорошая статья, я совсем недавно написал похожую. Радует что у вас в статье не устаревший clearfix.
    http://ymatuhin.ru/blog/float_and_clearfix/

    А вообще overflow решает 90% таких задач 🙂

  • 07.04.2015 22:58

    Я тоже не уловил смысла писать display: table;
    Есть ли какое то отличие ???
    До этого видел примеры без "table"

  • 2 вопроса.
    1.Для :after характерны следующие особенности.

    При добавлении :after к блочному элементу, значение свойства display может быть только: block, inline, none, list-item. Все остальные значения будут трактоваться как block. В нашем случае используется св-во table, насколько это правильно?

    2.А если решить данную проблему с помощью задания родительскому блоку св-ва overflow:hidden, насколько это решение будет правильным?

    • Евгений, не надо ля-ля аля "тополя". Карман не подшит, но бампер шуршит.