Как работает свойство CSS float left и float right

Вопросы о принципах работы свойств CSS float left и float right возникают с завидной регулярностью. Особенно больной темой это становится для верстальщиков и программистов, которые годами собирали макеты на таблицах, а тут их начинают заставлять работать с блоками. Дополнительно это усугубляется вопросами коссбраузерной верстки, хотя последнее время эта тема уже как-то стала не так сильно трепать нервы специалистам.

В любом случае, я решил вместо постоянных ответов на одни и те же вопросы, как работает свойство CSS float left и float right, написать пост и отправлять всех страждущих к нему.

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

Блоки в контейнере с установленными свойствами CSS float left и float right

Типичная проблема:

  1. Есть контейнер с двумя блоками или больше.
  2. У внутренних блоков задано свойство CSS float left или right.
  3. Если размера блоков не хватает, то контент снизу начинает лезть в блок и вся верстка разъезжается.

На иллюстрациях ниже показана пара подобных случаев.

Ситуация с двумя или более блоками со свойством CSS float left

Как должно быть:

Ситуация с двумя или более блоками со свойством CSS float left как должно быть

Как выглядит при ошибочной верстке:

Ситуация с двумя или более блоками со свойством CSS float left ошибка верстки

Ситуация, когда у одного блока свойство CSS float left, а у другого right

Как должно быть:

Ситуация, когда у одного блока свойство CSS float left, а у другого right как должно быть

Как выглядит при ошибочной верстке:

Ситуация, когда у одного блока свойство CSS float left, а у другого right ошибка верстки

Почему такая ситуация получилась

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

Все дело в том, что блоки с заданными свойствами float не влияют на изменение высоты своего контейнера.

Например: в первом случае у нас все блоки внутри контейнера плавающие. Поэтому высота контейнера будет равна нулю.

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

Решение 1 добавить пустой блок с CSS свойством clear: both

Перед закрывающим тегом контейнера необходимо поместить блок со свойством CSS clear:both. Тогда контейнер будет достроен до нижнего блока, поскольку это свойство блокирует влияние блоков со свойством CSS float left и float right.

Пример кода страницы:

<div class="container">

<div class="in_block">Эпсилон окрестность, 
общеизвестно, переворачивает абстрактный 
ряд Тейлора, как и предполагалось.</div>

<div class="in_block">Эпсилон окрестность, 
общеизвестно, переворачивает абстрактный 
ряд Тейлора, как и предполагалось.</div>

<div class="in_block">Эпсилон окрестность, 
общеизвестно, переворачивает абстрактный 
ряд Тейлора, как и предполагалось.</div>

<div class="clear"></div>

</div> <!-- end of .container -->

<p>Однако не все знают, что поле направлений соответствует определитель 
системы линейных уравнений, что неудивительно. К тому же определитель 
системы линейных уравнений категорически восстанавливает вектор, как и 
предполагалось. Окрестность точки по-прежнему востребована. Лемма, 
как следует из вышесказанного, существенно стабилизирует абстрактный 
расходящийся ряд, что несомненно приведет нас к истине. Лемма 
осмысленно раскручивает неопровержимый натуральный логарифм, 
дальнейшие выкладки оставим студентам в качестве несложной домашней 
работы.</p>

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

Пример кода страницы:

<div class="container">

<div class="in_block">Эпсилон окрестность, 
общеизвестно, переворачивает абстрактный 
ряд Тейлора, как и предполагалось.</div>

<div class="in_block">Эпсилон окрестность, 
общеизвестно, переворачивает абстрактный 
ряд Тейлора, как и предполагалось.</div>

<div class="in_block">Эпсилон окрестность, 
общеизвестно, переворачивает абстрактный 
ряд Тейлора, как и предполагалось.</div>

</div> <!-- end of .container -->

<div class="clear"></div>

<p>Однако не все знают, что поле направлений соответствует определитель 
системы линейных уравнений, что неудивительно. К тому же определитель 
системы линейных уравнений категорически восстанавливает вектор, как и 
предполагалось. Окрестность точки по-прежнему востребована. Лемма, 
как следует из вышесказанного, существенно стабилизирует абстрактный 
расходящийся ряд, что несомненно приведет нас к истине. Лемма 
осмысленно раскручивает неопровержимый натуральный логарифм, 
дальнейшие выкладки оставим студентам в качестве несложной домашней 
работы.</p>

Пример кода CSS:

.container {
	display: block;
}

.in_block {
	display: block;
	float: left;
	width: 100px;
	height: 100px;
	margin-right: 10px;
}

.clear {
	display: block !important;
	margin: 0px !important;
	padding: 0px !important;
	clear: both !important;
	float: none !important;
	height: 1px !important;
	width: auto !important;
}

Методически – не самое элегантное решение, хотя заслуживает право на жизнь, поскольку вполне эффективно. Явным недостатком можно назвать тот факт, что нам приходится добавить лишний код в текст страницы.

Решение 2 явно указать высоту контейнера

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

.container {
	display: block;
	height: 100px;
}

.in_block {
	display: block;
	float: left;
	width: 100px;
	height: 100px;
	margin-right: 10px;
}

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

Решение 3 задать свойство CSS overflow для контейнера

Если вы зададите значение свойства контейнера overflow равным auto или hidden, браузер будет перестраивать контейнер, таким образом, чтоб уместить все плавающие блоки и не отображать полосы прокрутки.

Если для свойства overflow вы задали значение auto, то будьте готовы к тому, что в некоторых ситуациях полосы прокрутки все же могут появиться. Поэтому следует всесторонне проверять верстку в разных режимах.

Пример кода CSS:

.container {
	display: block;
	overflow: auto;
}

.in_block {
	display: block;
	float: left;
	width: 100px;
	height: 100px;
	margin-right: 10px;
}

Два блока на одном уровне с указанными свойствами CSS float left и float right

Типичная ситуация: текст, который обтекает два блока с неким содержимым. При этом блоки расположены по сторонам от текста.

Как должно быть:

Два блока на одном уровне с указанными свойствами CSS float left и float right как должно быть

Как выглядит при ошибочной верстке:

Два блока на одном уровне с указанными свойствами CSS float left и float right ошибка верстки

Причина появления такой ситуации

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

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

Решение проблемы

  1. Проверьте наличие значений свойств CSS float left и float right.
  2. Установите блоки перед контентом, который должен их обтекать.