Очистка свойства float

Подробно описаны приемы отмены свойства float с демонстрацией на примерах.

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

HTML
<div class="container">Lorem ipsum dolor sit amet, consectetur ...
  <div class="leftbox">
    Lorem Ipsum - это текст-"рыба", часто используемый в печати и ... c начала XVI века. 
  </div>
  <div class="staticbox">
    Давно выяснено, что при оценке дизайна и композиции ... дожидаются своего настоящего рождения.
  </div>
</div>     <!-- конец контейнера -->     

CSS
.container {
  width:850px;
  background:yellow;
  margin: auto auto;
}
.leftbox {
  float:left;
  width: 400px;
  height:300px;
  background:red;
  color:white;
  margin-left:30px;
}
.staticbox {
  background:gray;
  color:yellow;
}

Вот, что в итоге получилось.

Изображение исходной верстки.

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

Использование пустого блока

Наверняка многие знают, что для отмены плавающей разметки в HTML используется дополнительный пустой div. Но где его ставить, в конце контейнера или после контейнера? Давайте рассмотрим оба варианта. В обоих случаях CSS будет одинаковым

CSS
.container {
  width:850px;
  background:yellow;
  margin: auto auto;
}
.leftbox {
  float:left;
  width: 400px;
  height:300px;
  background:red;
  color:white;
  margin-left:20px;
}
.staticbox {
  background:gray;
  color:yellow;
}
.clear {
  clear:both;
}

Сначала поставим пустой очищающий div за контейнером.

HTML
<div class="container">Lorem ipsum dolor sit amet, consectetur ...
  <div class="leftbox">
Lorem Ipsum - это текст-"рыба", часто используемый в печати и ...
  </div>
</div>     <!-- конец контейнера -->     
<div class="clear"></div>
<div class="staticbox">
Давно выяснено, что при оценке дизайна и композиции .."
</div>

Результат очистки пустым div после контейнера.

Желаемого мы добились, но получилась дырка в фоне контейнера, впрочем, если этот фон совпадает с фоном его родителя (<div class=»wrapper»>), то все будет в порядке.

Теперь поставим пустой очищающий div в конце контейнера.

HTML
<div class="container">Lorem ipsum dolor sit amet, consectetur ...
  <div class="leftbox">
Lorem Ipsum - это текст-"рыба", часто используемый в печати и ...
  </div>
  <div class="clear"></div>
</div>     <!-- конец контейнера -->     
<div class="staticbox">
Давно выяснено, что при оценке дизайна и композиции .."
</div>

Результат очистки пустым div в конце контейнера.

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

Недостатки.
Прием с пустым дивом считается не совсем правильным, т.к. в структуре кода появляется пустой div элемент, а это семантически не верно.

Использование overflow:hidden

Если контейнеру, содержащему добавить правило overflow: hidden, то мы получим результат, аналогичный предыдущему. Берем HTML код исходного примера, а в CSS исходного примера классу контейнера добавим такое правило.

CSS
.container {
  overflow: hidden;
  zoom: 1; /* или height: 1%; - для корректной работы старых IE */
}  

Результат очистки свойством overflow:hidden.

Недостатки.
В некоторых случаях метод не применим. Например, в случае, когда контейнер содержит элементы, выходящие за пределы его размеров(выпадающее меню, абсолютное позиционирование).

Использование плавающего контейнера

Очистка происходит, если контейнер, содержащий плавающие элементы, также сделать плавающим. Такой контейнер не будет схлопываться, т.к. принимает высоту наиболее высокого элемента. Побочный эффект этого решения в том, что мы добавляем другой плавающий элемент на страницу, хотя в большинстве случаев хотим, чтобы он вел себя, как блочный элемент в нормальном потоке. Решение: установите для контейнера width:100%, это заставит браузер поставить разрыв строки перед содержимым контейнера.

CSS
.container {
    float: left;
    width: 100%;
}  

Результат очистки плавающим контейнером.

Недостатки.
1. Установка ширины 100% может конфликтовать с требуемым заполнением.
2. IE может в некоторых случаях добавить нижний отступ margin-bottom.

Использование псевдоэлемента :after

Еще один способ вернуться к нормальному потоку размещения использует псевдоэлемент :after.
Опять используем верстку исходного примера, а в CSS классу контейнера добавляем следующее.

CSS
.container:after {
    content: ".";
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
}

Для любителей поддерживать старые IE 6 и IE7 необходимо добавить такое дополнительное правило, чтобы установить hasLayout для них (по поводу hasLayout см. http://habrahabr.ru/post/50175/).
Дополнительное CSS правило для старых IE.

.container {
    height: 1%;
}  

Результат очистки всевдоэлементом :after.

Недостатки.
1. IE6 и IE7 не поддерживают псевдокласс :after, поэтому надо использовать дополнительное CSS свойство.
2. Генерируется контент, не имеющий семантического смысла.