Обтекание: float
Свойство float («плавать») сдвигает элемент к левому или правому краю, а текст обтекает его, как в газете или журнале. Когда-то на float строили целые сайты. Сегодня у него осталась одна честная задача — обтекание картинки текстом, но в старом коде он встречается постоянно.
Обтекание картинки
float: left прижимает картинку к левому краю, и строки текста идут справа от неё, а ниже — снова на всю ширину:
<style>
.photo { float: left; width: 120px; height: 120px; margin: 0 12px 8px 0; }
</style>
<img class="photo" src="/media/photo-200x200.jpg" alt="Горы и вода">
<p>Фьорды — узкие морские заливы между высокими скалами. Их берега поднимаются почти отвесно, а вода внизу бывает удивительно спокойной. Туристы приезжают сюда ради видов, пеших маршрутов и прогулок на лодке. Летом солнце здесь почти не заходит, и гулять можно до поздней ночи.</p>Внешний отступ справа и снизу не даёт тексту прилипнуть к картинке.
Значения float
| Значение | Что делает |
|---|---|
left | прижимает элемент влево, текст обтекает справа |
right | прижимает элемент вправо, текст обтекает слева |
none | без обтекания (по умолчанию) |
float: right подходит, например, для врезки — короткой цитаты сбоку от статьи:
<style>
.quote { float: right; width: 140px; margin: 0 0 8px 12px; padding: 8px; border-left: 4px solid gold; font-style: italic; }
</style>
<p><span class="quote">«Лучший вид — после трудного подъёма»</span>Маршрут на смотровую площадку занимает около двух часов. Тропа идёт по камням, поэтому нужна удобная обувь. Наверху дует ветер, так что возьмите куртку даже в жаркий день.</p>Родитель схлопывается
Плавающий элемент выпадает из обычного потока: родитель не учитывает его высоту. Если текста мало, картинка вылезает за рамку контейнера:
<style>
.card { border: 2px solid steelblue; padding: 8px; }
.card img { float: left; width: 80px; height: 80px; margin-right: 8px; }
</style>
<div class="card">
<img src="/media/photo-200x200.jpg" alt="Горы и вода">
Короткая подпись.
</div>display: flow-root
Чтобы контейнер охватил плавающий элемент целиком, ему задают display: flow-root. Блок становится отдельной областью, которая учитывает всё, что плавает внутри:
<style>
.card { display: flow-root; border: 2px solid steelblue; padding: 8px; }
.card img { float: left; width: 80px; height: 80px; margin-right: 8px; }
</style>
<div class="card">
<img src="/media/photo-200x200.jpg" alt="Горы и вода">
Короткая подпись.
</div>Рамка теперь проходит под картинкой.
clear — начать ниже
Свойство clear запрещает элементу стоять рядом с плавающими: он опускается ниже них. clear: left уходит ниже левых, clear: right — ниже правых, clear: both — ниже любых:
<style>
img { float: left; width: 80px; height: 80px; margin-right: 8px; }
h3 { clear: both; margin: 8px 0 0; }
</style>
<img src="/media/photo-200x200.jpg" alt="Горы и вода">
<p>Текст рядом с картинкой.</p>
<h3>Новый раздел — под картинкой</h3>Уберите clear: both — и заголовок встанет справа от картинки.
float в старом коде
До flexbox колонки и сетки строили из плавающих блоков. Чтобы родитель не схлопывался, к нему добавляли класс-«хак» clearfix:
.clearfix::after {
content: "";
display: table;
clear: both;
}Встретив такой код, знайте: это раскладка из прошлого. Новую раскладку делают на flexbox и grid, а float оставляют для обтекания текстом.
Частая ошибка
float не действует внутри flex- и grid-контейнера: элементы там расставляет сам контейнер, и плавание игнорируется:
<style>
.row { display: flex; gap: 8px; padding: 8px; background: whitesmoke; }
.row div { padding: 8px; background: lightskyblue; }
.right { float: right; }
</style>
<div class="row">
<div>Первый</div>
<div class="right">float: right не сработал</div>
</div>Чтобы во flex-контейнере отодвинуть элемент вправо, используют margin-left: auto.