Правильное использование CSS свойства float может стать непростой задачей даже для опытного верстальщика. В этой статье собраны варианты применения float, а также некоторые ошибки, с наглядными примерами.
![](https://habrastorage.org/r/w780q1/storage2/eb8/78d/19f/eb878d19febb6064b670cbffa380d639.jpg)
Некоторые элементы в CSS являются блочными и поэтому начинаются с новой строки. Например, если расположить два абзаца с тегами P, то они будут находиться друг под другом. Другие же элементы являются «строчными», т.е. отображаются на странице в одну строку.
Один из способов переназначить элементам тип обтекания — это использование свойства float. Классический пример — использование float для выравнивания картинки по левому или правому краю. Вот простой HTML-код картинки и абзаца:
Они отображаются с новой строки:
![](https://habrastorage.org/r/w780q1/storage2/f85/00d/e48/f8500de487f6653d513b712c1d83e37c.jpg)
Добавляем немного CSS картинке:
Получается выравнивание по правому краю:
![](https://habrastorage.org/r/w780q1/storage2/b23/197/523/b23197523078ce45ba0247e984556ded.jpg)
Если текста больше, то абзац будет обтекать картинку:
![](https://habrastorage.org/r/w780q1/storage2/785/387/599/7853875995c91e1ef348f5091b37335f.jpg)
Допустим, нам нужно сделать отступ в 20 пикселей между картинкой и текстом. Вот такая конструкция работать не будет:
Правильно вот так:
![](https://habrastorage.org/r/w780q1/storage2/214/4ba/274/2144ba27498d56329a262d1dc595ac2e.jpg)
Почему же не работает отступ для абзаца? Чтобы разобраться, добавим рамку:
Результат может вас удивить:
![](https://habrastorage.org/r/w780q1/storage2/05a/3e7/cb9/05a3e7cb97b9f55ef39a7e7213611f37.jpg)
Оказывается, картинка находится внутри абзаца! Поэтому и не работает свойство margin в первом случае. Чтобы исправить это, можно применить float:left к абзацу и указываем абсолютную ширину:
![](https://habrastorage.org/r/w780q1/storage2/6df/dd4/cad/6dfdd4cada9a698eed114875c1d914c3.jpg)
Перейдем к более сложным вариантам использования float: к правилам, регулирующим плавающие объекты. Это бывает необходимо при верстке галереи изображений. Например:
По умолчанию каждый элемент списка появится с новой строки. Если применить к каждому float:left, изображения встанут в один ряд с переносом строки:
![](https://habrastorage.org/r/w780q1/storage2/8b1/2f6/6ff/8b12f66ff896d435721db2cca1b7a0d1.jpg)
Но что, если изображения разной высоты?
![](https://habrastorage.org/r/w780q1/storage2/f1e/887/b85/f1e887b8587754ea4941844667d89bbd.jpg)
Если мы добавим элементам списка отображение в одну строку, получится немного симпатичнее:
![](https://habrastorage.org/r/w780q1/storage2/6d6/7d7/c76/6d67d7c76d7930f89b8aae3da17d1296.jpg)
А теперь выравниваем по вертикали:
![](https://habrastorage.org/r/w780q1/storage2/6db/97d/3cb/6db97d3cb9c0c9e62558f66300c752be.jpg)
Следует помнить, что в случае большей высоты картинок, остальные изображения обтекают только одно предыдущее, например:
![](https://habrastorage.org/r/w780q1/storage2/69d/840/508/69d840508244103fe5b45ae54678c3b0.jpg)
Пример изменения очередности элементов — например, у нас есть список элементов по порядку:
Если мы хотим расположить их в обратном порядке, просто применяем float:right вместо float:left, и не придется менять порядок в HTML:
![](https://habrastorage.org/r/w780q1/storage2/392/9c5/3db/3929c53db90ae128ca5dbb88c49eaf34.jpg)
С помощью float удобно группировать элементы на странице, но большой проблемой становится то, что последующие элементы (текст или блок) также получают свойство обтекания. Например, у нас есть блок картинок:
![](https://habrastorage.org/r/w780q1/storage2/a10/c8d/c2f/a10c8dc2fd1c883124610feb1b7cf90e.jpg)
Текст под ним начинает обтекать весь блок:
![](https://habrastorage.org/r/w780q1/storage2/d7c/494/1e8/d7c4941e844b42bc55cbe6bbfe23a453.jpg)
Чтобы избежать этого, необходимо использовать свойство clear. Если применим его ко второму изображению:
Получим вот, что:
![](https://habrastorage.org/r/w780q1/storage2/de4/20d/125/de420d12556e2ae176fac18319c79f7f.jpg)
В этом случае остальные изображения продолжают наследовать float:left. Соответсвенно текст будет отображаться коряво:
![](https://habrastorage.org/r/w780q1/storage2/eb8/78d/19f/eb878d19febb6064b670cbffa380d639.jpg)
Нужно применить clear:both к абзацу:
Наша проблема решена:
![](https://habrastorage.org/r/w780q1/storage2/b0a/642/692/b0a64269288e169ef715f48945e16bdd.jpg)
Теперь предположим, что нам необходимо установить фон для галереи из предыдущих примеров. Если бы элементы были не плавающими, то получилось бы вот, что:
![](https://habrastorage.org/r/w780q1/storage2/112/917/500/11291750039280e3005fea1abd2ab131.jpg)
Но если элементам списка применить float:left, фон совсем пропадает:
![](https://habrastorage.org/r/w780q1/storage2/a10/c8d/c2f/a10c8dc2fd1c883124610feb1b7cf90e.jpg)
Если мы сначала устанавливаем высоту для UL:
![](https://habrastorage.org/r/w780q1/storage2/081/9be/f7d/0819bef7da0c0d81048a37043aaae08f.jpg)
Это тоже не решает проблему, т.к. размеры фона заданы абсолютно. Нам поможет класс clearfix, который будет применен к div на том же уровне, что и элементы UL.
Существует еще одно решение, с использованием overflow:
![](https://habrastorage.org/r/w780q1/storage2/2bd/537/52d/2bd53752daf504951c83d7e06ee4d145.jpg)
![](https://habrastorage.org/storage2/eb8/78d/19f/eb878d19febb6064b670cbffa380d639.jpg)
Что такое float?
Некоторые элементы в CSS являются блочными и поэтому начинаются с новой строки. Например, если расположить два абзаца с тегами P, то они будут находиться друг под другом. Другие же элементы являются «строчными», т.е. отображаются на странице в одну строку.
Один из способов переназначить элементам тип обтекания — это использование свойства float. Классический пример — использование float для выравнивания картинки по левому или правому краю. Вот простой HTML-код картинки и абзаца:
<img src="http://lorempixum.com/200/200/" />
<p>Lorem ipsum...</p>
Они отображаются с новой строки:
![](https://habrastorage.org/storage2/f85/00d/e48/f8500de487f6653d513b712c1d83e37c.jpg)
Добавляем немного CSS картинке:
img {
float: right;
margin: 20px;
}
Получается выравнивание по правому краю:
![](https://habrastorage.org/storage2/b23/197/523/b23197523078ce45ba0247e984556ded.jpg)
Если текста больше, то абзац будет обтекать картинку:
![](https://habrastorage.org/storage2/785/387/599/7853875995c91e1ef348f5091b37335f.jpg)
Допустим, нам нужно сделать отступ в 20 пикселей между картинкой и текстом. Вот такая конструкция работать не будет:
p {margin: 20px;}
Правильно вот так:
img {margin: 20px;}
![](https://habrastorage.org/storage2/214/4ba/274/2144ba27498d56329a262d1dc595ac2e.jpg)
Почему же не работает отступ для абзаца? Чтобы разобраться, добавим рамку:
p {
border: solid 1px black;
}
Результат может вас удивить:
![](https://habrastorage.org/storage2/05a/3e7/cb9/05a3e7cb97b9f55ef39a7e7213611f37.jpg)
Оказывается, картинка находится внутри абзаца! Поэтому и не работает свойство margin в первом случае. Чтобы исправить это, можно применить float:left к абзацу и указываем абсолютную ширину:
img {
float: right;
margin: 20px;
}
p {
float: left;
width: 220px;
margin: 20px;
}
![](https://habrastorage.org/storage2/6df/dd4/cad/6dfdd4cada9a698eed114875c1d914c3.jpg)
Странные правила float
Перейдем к более сложным вариантам использования float: к правилам, регулирующим плавающие объекты. Это бывает необходимо при верстке галереи изображений. Например:
<ul>
<li><img src="1450823466601083332032"/></li>
<li><img src="http://placehold.it/100x150&text=2"/></li>
<li><img src="1450823466394721548724"/></li>
<li><img src="1450823466376067888878"/></li>
<li><img src="1450823466279266032276"/></li>
<li><img src="http://placehold.it/100x150&text=6"/></li>
<li><img src="http://placehold.it/100x100&text=7"/></li>
</ul>
По умолчанию каждый элемент списка появится с новой строки. Если применить к каждому float:left, изображения встанут в один ряд с переносом строки:
li {
float: left;
margin: 4px;
}
![](https://habrastorage.org/storage2/8b1/2f6/6ff/8b12f66ff896d435721db2cca1b7a0d1.jpg)
Но что, если изображения разной высоты?
![](https://habrastorage.org/storage2/f1e/887/b85/f1e887b8587754ea4941844667d89bbd.jpg)
Если мы добавим элементам списка отображение в одну строку, получится немного симпатичнее:
li {
display: inline;
}
![](https://habrastorage.org/storage2/6d6/7d7/c76/6d67d7c76d7930f89b8aae3da17d1296.jpg)
А теперь выравниваем по вертикали:
img {
vertical-align: top;
}
![](https://habrastorage.org/storage2/6db/97d/3cb/6db97d3cb9c0c9e62558f66300c752be.jpg)
Следует помнить, что в случае большей высоты картинок, остальные изображения обтекают только одно предыдущее, например:
![](https://habrastorage.org/storage2/69d/840/508/69d840508244103fe5b45ae54678c3b0.jpg)
Пример изменения очередности элементов — например, у нас есть список элементов по порядку:
<ul>
<li><img src="1450823466601083332032"/></li>
<li><img src="http://placehold.it/100x100&text=2"/></li>
<li><img src="1450823466394721548724"/></li>
<li><img src="1450823466376067888878"/></li>
<li><img src="1450823466279266032276"/></li>
<li><img src="http://placehold.it/100x100&text=6"/></li>
</ul>
Если мы хотим расположить их в обратном порядке, просто применяем float:right вместо float:left, и не придется менять порядок в HTML:
![](https://habrastorage.org/storage2/392/9c5/3db/3929c53db90ae128ca5dbb88c49eaf34.jpg)
С помощью float удобно группировать элементы на странице, но большой проблемой становится то, что последующие элементы (текст или блок) также получают свойство обтекания. Например, у нас есть блок картинок:
![](https://habrastorage.org/storage2/a10/c8d/c2f/a10c8dc2fd1c883124610feb1b7cf90e.jpg)
Текст под ним начинает обтекать весь блок:
![](https://habrastorage.org/storage2/d7c/494/1e8/d7c4941e844b42bc55cbe6bbfe23a453.jpg)
Чтобы избежать этого, необходимо использовать свойство clear. Если применим его ко второму изображению:
ul li:nth-child(2) {
clear: left;
}
Получим вот, что:
![](https://habrastorage.org/storage2/de4/20d/125/de420d12556e2ae176fac18319c79f7f.jpg)
В этом случае остальные изображения продолжают наследовать float:left. Соответсвенно текст будет отображаться коряво:
![](https://habrastorage.org/storage2/eb8/78d/19f/eb878d19febb6064b670cbffa380d639.jpg)
Нужно применить clear:both к абзацу:
p {
clear: both;
}
Наша проблема решена:
![](https://habrastorage.org/storage2/b0a/642/692/b0a64269288e169ef715f48945e16bdd.jpg)
Теперь предположим, что нам необходимо установить фон для галереи из предыдущих примеров. Если бы элементы были не плавающими, то получилось бы вот, что:
ul {
background: gray;
}
![](https://habrastorage.org/storage2/112/917/500/11291750039280e3005fea1abd2ab131.jpg)
Но если элементам списка применить float:left, фон совсем пропадает:
![](https://habrastorage.org/storage2/a10/c8d/c2f/a10c8dc2fd1c883124610feb1b7cf90e.jpg)
Если мы сначала устанавливаем высоту для UL:
ul {
height: 300px;
}
![](https://habrastorage.org/storage2/081/9be/f7d/0819bef7da0c0d81048a37043aaae08f.jpg)
Это тоже не решает проблему, т.к. размеры фона заданы абсолютно. Нам поможет класс clearfix, который будет применен к div на том же уровне, что и элементы UL.
.clearfix {
clear: both;
}
Существует еще одно решение, с использованием overflow:
ul {
overflow: auto;
}
![](https://habrastorage.org/storage2/2bd/537/52d/2bd53752daf504951c83d7e06ee4d145.jpg)
Девять правил float-элементов:
- Плавающие элементы не могут выходить за край своего контейнера-родителя.
- Каждый плавающий элемент будет отображаться справа или ниже от предыдущего при float:left, либо слева и ниже, при float:right.
- Блок с float:left не может быть правее, чем блок с float:right.
- Плавающий элемент не может выходить за пределы верхней границы своего контейнера.
- Плавающий элемент не может располагаться выше, чем родительский блок или предыдущий плавающий элемент.
- Плавающий элемент не может располагаться выше, чем предыдущая строка inline-элементов
- Плавающий блок должен быть расположен как можно выше.
- Один плавающий элемент, следующий за другим, не может выходить за пределы своего контейнера — происходит перенос на следующую строку.
- Блок с float:left должен быть расположен как можно левее, а с float:right — как можно правее.