Отмена обтекания блоков (float) наиболее часто встречающаяся операция при верстке HTML страниц. Мы рассмотрим все известные способы отменить действие CSS свойства float.
Прежде чем мы углубимся в методы очистки потока, давайте взглянем на проблему, которую мы пытаемся решить.
Типичный случай HTML верстки
Блоки .el-1 и .el-2 размещаются бок о бок внутри контейнера .container, и один элемент .main следует после .container:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Пример верстки</title>
<style>
.container {border:1px solid black;}
div {float:left;}
.el-1 {width:200px; height:120px; background: yellow;}
.el-2 {width:120px; height:100px; background: pink;}
.main {background: orange; height:50px;}
</style>
</head>
<body>
<section class="container">
<div class="el-1"></div>
<div class="el-2"></div>
</section>
<section class="main"></section>
</body>
</html>
Мы хотим, чтобы высота контейнера .container была равной высоте самого длинного из его дочерних элементов (т.е. либо .el-1, либо .el-2) и чтобы блок .main, чтобы был после блока .container.
А вот, что мы видим: .container (черная рамка) схлопнулся, как будто в нем ничего нет, блок .main (блок с рыжим фоном) находится под блоком .container, как мы и хотели, но при этом он прячется за блоки .el-1 (с желтым фоном) и .el-2 (с розовым фоном). Черт знает что! Видел бы это мой начальник - непременно сказал бы мне,- "Используй, Шурик, табличную верстку". К счастью, времена, когда web-страницы верстались таблицами уже давно прошли и мы отлично обойдемся и без них. Не верите? Читайте дальше.
Несмотря на то, что многие считают это багом браузера, - это всего лишь принцип, по которому работают плавающие элементы. Следовательно нам нужно заставить родительский элемент расширяться, чтобы полностью вмещать дочерние элементы. Тогда, следующие элементы будут располагаться под контейнером.
Способ 1: метод старой школы
Как вам известно, CSS свойство clear устанавливает с какой стороны элемента запрещено его обтекание другими элементами, следовательно это свойство может предотвратить налезание элементов поверх плавающих. Идея заключается в следующем: вставьте пустой элемент, который свойство clear
под обтекаемыми блоками. Это использовать определенный класс для подобного элемента - давно устоявшаяся традиция, так что вы можете использовать его в вашем HTML. Вот классический CSS код:
.clear {
clear: both;
}
Который применим к нашей HTML верстке:
<section class="container">
<div class="el-1">Я обтекаемый</div>
<div class="el-2">И я обтекаемый...</div>
<br class="clear">
</section>
<section class="main">
Браво, вам удалось отменить обтекание
</section>
Наш демо-пример, реализуемый с помощью этого метода:
Если вас не волнует схлопывающийся контейнер, а только неправильно расположенный блок .main, то вы можете также поместить "очищающий поток" элемент br после контейнера. Но, если вы решите сделать так, то гораздо проще будет просто добавить свойство clear
самому элементу .main.
Это простой и понятный метод. Тем не менее, в современной верстке практикуется отделение контента от стиля, поэтому лучше его не использовать.
Способ 2: свойство overflow
Используя свойство overflow в теге .container, мы можем заставить контейнер расшириться до высоты размещенных элементов. Наш CSS будет выглядеть следующим образом:
.container {
overflow: hidden; /* или "auto" */
}
Наш HTML останется таким же, каким и был изначально, без дополнительных элементов. Вот, что мы получим в итоге:
К сожалению, у этого метода есть недостаток: любой дочерний элемент, который выступает за пределы контейнера, будет либо обрезан (в случае overflow: hidden;
), либо вызовет появление полос прокрутки (в случае overflow: auto;
).
Способ 3: класс “clearfix”
Мы создаем класс .clearfix с псевдо-элементами ::before и ::after и задаем им display: table
, что создает анонимную ячейку таблицы. Этот класс будет использоваться для очищения плавающих элементов. CSS код выглядит так:
.clearfix:before,
.clearfix:after {
content: "";
display: table;
}
.clearfix:after {
clear: both;
}
.clearfix {
zoom: 1; /* ie 6/7 */
}
Изменим немного HTML код добавив к классу container класс clearfix:
<section class="container clearfix">
<div class="el-1">Я обтекаемый</div>
<div class="el-2">И я обтекаемый...</div>
</section>
<section class="main">
Браво, вам удалось отменить обтекание
</section>
Вот результат работы наешго новвого класса:
если вам не нужна поддержка браузеров ниже IE8, то наш код значительно сократится:
.clearfix:after {
content: "";
display: table;
clear: both;
}
Способ 4: значение contain-floats для min-height
Спецификация W3C добавила новое значение для свойства min-height (и для других свойств min/max), для решения этой проблемы. Выглядит оно так:
.container {
min-height: contain-floats;
}
Этот код дает практически тот же эффект, что и clearfix, или overflow, но с помощью одной строки кода и, к тому же он лишен тех недостатков, о которых мы говорили ранее. К сожалению, пока ни один из браузеров не поддерживает это свойство, так что просто имейте его ввиду.
Итак, у вас есть целый набор различных «clearfix» методов. Применение класса .clearfix стало стандартом, и я очень рекомендую использовать его вместо прежних двух методов.