Подробно о свойстве float. Понятие о потоке

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

Что такое "float"?

Float это свойство CSS позиционирования. Что бы понять его суть и происхождение нужно обратить своё внимание на печатный дизайн. В печатных макетах изображение может быть расположено так, что текст обтекает его. Обычно это и называется "обтекание текстом ".



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



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

Установка свойства float для элементов с помощью CSS выглядит следующим образом:

#sidebar { float: right; }

Есть четыре допустимых значения для свойства float - left , right , none , inherit . Первые два, left и right указывают направления расположения - слева и справа, соответственно. None - значение по умолчанию, указывает что элемент не плавающий и inherit указывающий элементу наследовать значение свойства float от родительского элемента.

Для чего используется float?

Помимо простого примера обтекания текста вокруг изображения, float можно использовать для создания веб макетов.



Float , так же удобно использовать для небольших элементов макета. К примеру, возьмём этот небольшой фрагмент веб страницы. Если мы установим свойство float для небольшого изображения аватара, то когда изменится размер изображения обтекание измениться в соответствии с новыми размерами изображения:



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


Сброс обтекания

Clear родственное свойство свойству float . Элемент с установленным свойством clear не будет двигаться вверх обтекая элемент с установленным свойством float , но будет смещаться вниз игнорируя обтекание. И снова иллюстрация, которая объяснит всё без лишних слов.



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

#footer { clear: both; }

Свойство clear имеет четыре значения. Both используется для сброса обтекания в обоих направлениях. Left и Right используются для сброса одного направления - левого или правого, соответственно. None - значение по умолчанию. Inherit может быть пятым значением, но оно на удивление не поддерживается Internet Explorer . Сброс только левого или правого обтекания встречается довольно редко, но имеет практическую пользу.


Великий коллапс

Одна вещь в работе с float вызывает недоумение, это то какое влияние это свойство оказывает на родительские элементы. Если родительский элемент не содержит элементов, кроме плавающего, то его высота буквально коллапсирует. Это не всегда заметно, особенно если родительский элемент не имеет заметного фона, но важно об этом помнить.



Но альтернатива такого коллапса ещё хуже. Рассмотрим следующий сценарий:



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

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

Техники отмены обтекания

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

Метод пустого блока.

Это в буквальном смысле пустой блок.

. Иногда можно встретить элемент
или любой другой случайный элемент, но div наиболее распространён поскольку он не имеет в браузерах стиля по умолчанию, не имеет специальной функции и вряд ли будет в общем стиле CSS . Этот метод отвергают семантические пуристы поскольку его присутствие не имеет контекстного смысла на странице и он расположен там только для внешнего вида. Конечно, в строгом смысле они правы, но он выполняет свою работу и никому не вредит.

Метод переполнения.

Основан на указании CSS свойства overflow для родительского элемента. Если это свойство установлено в auto или hidden для родительского элемента, то он будет расширятся вслед за плавающим элементом эффективно сбрасывая обтекание его для последующих элементов. Этот метод может быть семантически красив, так как не требует дополнительных элементов. Однако, как вы видите мы добавили новый div для использования этого метода, что эквивалентно использованию не семантического пустого блока и менее гибко. Так же следует помнить, что свойство overflow предназначено не для отключения обтекания. Будьте осторожны что бы случайно не скрыть контент или вызвать нежелательные полосы прокрутки.

Метод лёгкой очистки.

Использует CSS псевдо-селектор (:after ) для удаления обтекания. Вместо использования свойства overflow для родительского элемента установите дополнительный класс для него, например "clearfix" и используйте следующий стиль CSS :

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

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

Разные ситуации требуют разных методов сброса обтекания. Возьмём для примера сетку разнотипных блоков.



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


Проблемы с плавающими элементами

Плавающие элементы часто ругают из-за их хрупкости. Большая часть этой хрупкости идёт от IE6 и его float-ориентированных багов . Но поскольку всё больше и больше разработчиков отказывается от поддержки IE6 , вы можете об этом не думать, но для тех кто заботиться о совместимости вот краткий список.

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



Быстрое решение проблемы : используйте overflow: hidden; для обрезания излишков.

Баг с двойными полями (double margin bug) - ещё одна вещь о которой необходимо помнить работая с IE6 . Этот баг выражается в том, что если поле находится с той же стороны куда ориентирован float , поле удваивается. Например:

Мы получим слева поле в 40 px ., вместо 20 px .

Быстрое решение проблемы : установить display: inline для плавающего блока, и не волнуйтесь элемент останется блочным.

3х пиксельный толчок (3px Jog) . Суть этого бага в том, что текст расположенный рядом с плавающим элементом странным образом смещается на три пикселя, как будто под воздействие силового поля расположенного вокруг плавающего элемента. Быстрое решение проблемы : установить ширину и высоту пострадавшего текста.

В IE7 появляется Баг нижнего отступа (bottom margin bug) , когда родительский элемент является плавающим и его потомок расположенный внутри него тоже плавающий элемент. Нижнее поле (margin-bottom ) потомка игнорируется, элементом предком. Быстрое решение проблемы : Использовать нижнее поле (padding-bottom ) в родительском элементе, вместо нижнего отступа (margin-bottom ) потомка.

Подробно описывается CSS свойство float , особенности применения и тонкости использования, приведены виды позиционирования HTML элементов.

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

Терминология

Чтобы не было двусмысленностей, договоримся о терминах.
Float (плавающий элемент) – под float или плавающим элементом в статье подразумевается блочный элемент с установленным CSS свойством float right или left .
Бокс – под термином бокс подразумевается воображаемый прямоугольник, в который заключен каждый элемент HTML разметки. В соответствии с англоязычной терминологией этот воображаемый прямоугольник будем называть боксом.
Если про бокс не очень понятно, то настоятельно рекомендую более подробно познакомиться с боксами и их свойствами в , т.к. этот термин достаточно часто используется в статье, а главное — это основа всей HTML верстки.
Примечание. Далее в тексте будут встречаться подчеркнутые слова . Таким образом я хочу обратить особе внимание на определенное свойство или качество элемента.

Виды позиционирования HTML элементов

Для ясного представления изложенного надо также знать основные принципы отображения элементов в HTML документах.
Согласно w3.org в WEB разметке используется три схемы размещения элементов в Web документах.
Нормальный поток – в CSS 2.1 нормальный поток Web документа включает элементы, представленные, как блочные боксы, элементы, форматированные, как строчные, и относительное позиционированние блочных и строчных боксов.
Другими словами, нормальный поток включает обычные элементы верстки, у которых не установлены float , равный left/right , или position , равный absolute/fixed .
Float – плавающий элемент вначале размещается в соответствии с правилами размещения в нормальном потоке, потом выводится из этого потока и смещается в своей строке влево или вправо, насколько это возможно.
Четко усвойте следующее важное правило. Так как плавающие элементы выводятся из нормального потока документа, то блочные боксы нормального потока их не видят, но строчные боксы нормального потока их видят и обтекают по одной из сторон, к строчным боксам, в частности, относится обычный текст блочных боксов. А это означает, что если при своем размещении блочные боксы нормального потока не обращают никакого внимания на присутствие плавающих боксов, то содержимое этих боксов (строчные элементы) обтекают такие элементы.
Абсолютное позиционирование – при абсолютном позиционировании бокс полностью удаляется из нормального потока (не влияет на последующие) и размещается относительно позиции своего контейнера, т.е элемента, в котором он размещен.
Немного подробнее о потоках HTML документов вы можете прочитать в статье

Различия между плавающими(float) и позиционированными(position) элементами

В начале, на всякий случай напомню, в чем разница между плавающим (float ) и позиционированным (position ) элементами. Относительно позиционированный элемент со значением position:relative остается в нормальном потоке документа, но сдвигается относительно своего положения, другие элементы при этом не затрагиваются и остаются там, где они были. Это дает возможность элементам с относительным позиционированием перекрывать окружающие его элементы на странице. Если у элемента установлено position:absolute; или position:fixed; , то он удаляется из нормального потока и размещается в соответствии с правилами абсолютного позиционирования.
Плавающий элемент всегда удаляется из нормального потока документа и влияет на размещение окружающих элементов.

Вот теперь приступим.

Что такое float?

«Float» — одно из CSS свойств блочного элемента разметки, благодаря которому HTML элемент смещается в крайнее, доступное для размещения, левое или правое положение внутри содержащего этот элемент контейнера. Если в текущей строке контейнера по ширине не хватает места для его размещения, он смещается на следующую строку до тех пор, пока не сможет разместиться. Замечу, что ширина float элемента определяется его содержимым. В зависимости от установленного значения float , строчные элементы могут обтекать такой блочный элемент по одной из его горизонтальных сторон.
Свойство float может принимать следующие значения: none (по умолчанию), left, right и inherit .

Правила отрисовки float элементов

Что происходит, когда браузер встречает элемент, у которого свойство float отлично от none ?
Вначале такой бокс размещается, как обычный элемент, потом извлекается из нормального потока и сдвигается в левую или правую сторону до тех пор, пока не встретит такой же float элемент или границу своего родительского контейнера. В случае, если оставшегося места по горизонтали для элемента не хватает, браузер смещает его на следующую строку своего контейнера.
Поскольку float элемент извлечен из нормального потока, обычные блочные элементы без установленного свойства float не знают о его существовании и размещаются обычным способом, каждый на новой строке. Строчные же элементы разметки «видят» float бокс и обтекают его по одной из сторон в зависимости от значения — left или right .
Для наглядной демонстрации сказанного, приведу такой пример.

Нормальный бокс1.

float div1.

float div2.

Нормальный бокс2.

Вот что при этом отобразится браузером.

Демонстрация отрисовки float элементов

А теперь разберемся, что получилось. В примере приведено 4 блока, бокс1 и бокс2 отрисовываются браузером по умолчанию, т.е в нормальном потоке, а у внутренних элементов стоит float = left . Чтобы пример получился нагляднее, я добавил блокам фоновый цвет и отступы. Итак, в итоге блоки по умолчанию (1-й и 4-й) отобразились, как обычно, каждый на новой строке и занимают всю ширину(поскольку приведен screenshot разметки, ширина боксов ограничена шириной картинки ). Плавающие же (2-й и 3-й) были извлечены из нормального потока (т.е, 1-й и 4-й боксы их не видят, поэтому «нормальный бокс2» начинается под 1-м с начала строки) и смещены к левой границе контейнера. И хотя нормальные блочные боксы не видят плавающих, но строчный бокс последнего бокса(а это его текст) видит плавающие боксы и обтекает их с правой стороны.
Как видите, все в соответствии с вышеприведенным алгоритмом отрисовки float элементов.

Как используют float

Существует два основных способа использования свойства float .
Рассмотрим их.

Обтекание изображения текстом.

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

Текст обтекает изображение с float:left

Пример верстки страницы с текстом, обтекающим изображение.

CSS
img.alignleft {float: left; margin: 0 10px 10px 0}

В коде сверху и плавающий элемент img и обтекающий текст находятся внутри одного и того же контейнера p .
Обратите внимание, что в CSS стилях слева и справа плавающему элементу добавлены отступы. Это обычная практика, когда изображению добавляется пространство между ним и окружающим текстом.

Макеты с колонками

Свойство Float позволяет два блочных элемента располагать рядом друг с другом, а не начинать с новой строки. Это свойство плавающих элементов очень удобно использовать для создания колонок в документе. Чтобы получить макет с 2 колонками, достаточно задать обтекание(т.е. задать свойcтво float) двум DIVам.
Пример создания 2-х колоночного макета с помощью float.

HTML
‹div id="wrapper"›
‹div id="left-column"›‹div›
‹div id="right-column"›‹/div›
‹/div›

CSS
#left-column {float: left}
#right-column {float: left}

В примере оба внутренних DIVа получили обтекание слева, в итоге имеем 2 колонки. Вы также должны убедиться, что общая ширина двух внутренних столбцов (div) не превышает ширину родительского бокса, иначе вторая колонка перескочит на новую позицию, ниже первой колонки.
Добавив div заголовка над 2-мя колонками и div подвала с использованием свойства clear, вы получите простой и красивый 2-х колоночный макет.

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

Отмена свойства float

Нередко при работе с float бывает необходимо, чтобы последующие элементы разметки располагались не рядом с плавающим текущим, а как обычно, на следующей строке, т.е требуется вернуться к размещению элементов в соответствии с нормальным потоком.
Часто этого добиваются использованием свойства clear . Свойство clear принимает значения left, right, both, none (по умолчанию), и inherit . На практике используется первые 3 значения, причем в подавляющем большинстве случаев вы будете использовать clear: both.
Чаще всего, пожалуй, clear используется для того, чтобы div подвала страницы установить ниже ваших 2-х или 3-х плавающих колонок.


Будте внимательны. При использовании после плавающего элемента в новом боксе правила с clear , вы возвращаете этот бокс в нормальный поток, но при этом его свойство margin-top перестает работать. Зачастую эту ситуацию исправляют помещая перед требуемым в нормальном потоке боксом пустой div со свойством clear

. Справедливости ради надо заметить, что такой прием считается технически правильным, но семантичеки не корректным, т.к. в документе появляется пустой div контейнер.

Контейнер с float элементами

Первое, что нужно сделать при использовании контейнера для плавающих элементов, это быть уверенным, что ширины контейнера достаточно для установки элементов рядом друг с другом. Если вы установите у двух элементов свойство float:left для создания 2-х колоночной компоновки, а общая ширина элементов окажется больше ширины контейнера, то один из элементов перескочит на следующую строку. Это произойдет из-за того, что второй колонке не будет хватать места стоять в родительском боксе рядом с 1-й колонкой. Ниже приведены рисунки, иллюстрирующие подобную ситуацию.

Ранее упоминалось, что плавающие элементы убираются из нормального потока документа. Это приводит к интересной и запутанной проблеме, когда все элементы внутри контейнера плавающие. Обычно такое наблюдается, например, когда в div контейнере заголовка Web страницы находится изображение логотипа со свойством float:left . В заголовке также, как правило, с помощью свойства background-image приводится какое-либо фоновое изображение. В сумме имеем контейнер в нормальном потоке, который содержит плавающий элемент и пустой элемент в нормальном потоке, поскольку изображение выведено фоном. Проблема в том, что div заголовка содержит единственный не пустой элемент – плавающее изображение логотипа, которое выпало из нормального потока. Поэтому браузер считает div заголовка пустым и устанавливает его высоту нулевой. Часто при этом говорят, что контейнер схлопнулся. Существует несколько путей решения этой проблемы. Вы можете явно задать высоту div контейнера не меньше высоты изображения. Это будет хорошо работать в случае с заголовком, как в приведенном примере, но такое по ряду причин не всегда возможно. Иногда добавляют пустой div с установленным свойством clear , чтобы следующие элементы не были плавающими.

HTML
‹div class="clear"›‹/div›

CSS
.clear { clear:both; }

Это удобно, если допускается иметь некоторое пустое пространство после плавающих элементов, т.к. некоторые браузеры для пустых div могут иметь по умолчанию конечные величины для height, margin, padding и.т.д.
Существует также метод использования свойства overflow в родительском элементе. Обычно используют overflow: hidden , но в зависимости от ситуации вы можете использовать overflow: auto или overflow-y вместо использования этого свойства в обоих направлениях. Использование свойства overflow защищает родительский контейнер от схлопывания.

Проблемы с float

Кроме проблемы схлопывающегося контейнера, свойство float имеет еще ряд проблем.
Старые версии Internet Explorer имеют баг двойного отступа(margin ). Если элементы обтекаются в одинаковом направлении и элементам также добавлены margin в том же направлении (left/left или right/right), IE удваивает величину margin . Простым решением является установка свойства display: inline для плавающего элемента, кстати это свойство помогает избавиться и от других багов вредного ишака. Кроме того, вы можете использовать условные комментарии для установки специфических margin для IE или для отдельных версий IE.
Другой проблемой является добавление элементов внутрь плавающего элемента, причем ширина добавляемых элементов больше ширины контейнера. Вы можете, например, добавить изображение внутрь плавающего элемента, при этом ширина изображения больше ширины контейнера. В зависимости от браузера это может привести к тому, что ваш плавающий элемент будет шире, чем предполагалось, или содержимое перекрывает ваше изображение. Убедитесь, что элементы внутри плавающего элемента не превышают ширину плавающего элемента.
Существует также проблема пропадания нижнего отступа (margin-bottom ). Нижний отступ плавающего элемента внутри других плавающих элементов может быть проигнорирован. Решение заключается в использовании padding вместо margin , если такое случается.

Итоги по float

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

  • Плавающие элементы выкладываются в нормальный поток документа, затем сдвигаются влево или вправо внутри родительского элемента в соответствии со значением float и удаляются из нормального потока документа.
  • Теги с установленными значениями float автоматически становятся блочными элементами.
  • Блочные боксы с установленным float располагаются рядом друг с другом, пока для них достаточно места. Если места в контейнере не хватает, они будут отображаться ниже плавающих элементов.
  • Ширина бокса с установленным свойством float определяется шириной его содержимого. Рекомендуется при разметке устанавливать ширину float элементам, иначе результат может быть непредсказуем, рекомендация не касается изображений, поскольку для них ширина подразумевается.
  • Плавающие и позиционированные элементы различны и ведут себя по разному. Вы не можете использовать свойства float и position в одном элементе.
  • Для сброса свойства обтекания для последующих элементов используйте CSS свойство clear .
  • Float бокс выводится из основного потока, поэтому блочные элементы в нормальном потоке размещаются так, как будто его нет, но строчные боксы этих элементов освобождают место для плавающего блока.
  • Контейнер с исключительно плавающими элементами, имеет нулевую высоту, т.к. float элементы выведены из нормального потока, поэтому родитель считает, что он пустой. Существуют способы борьбы с этим эффектом без дополнительной разметки, ознакомиться с ними можно, например, .
  • В отличие от элементов основного потока, вертикальные границы float бокcов не объединяются с границами соседних блоков.
  • Найдите наиболее подходящие для себя решения для разрешения проблем корректного отображения float элементов в Internet Explorer.

Надеюсь, изложенное поможет вам прояснить определенную путаницу при использовании CSS свойства float .

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

Что такое float?

Некоторые элементы в CSS являются блочными и поэтому начинаются с новой строки. Например, если расположить два абзаца с тегами P, то они будут находиться друг под другом. Другие же элементы являются «строчными», т.е. отображаются на странице в одну строку.

Один из способов переназначить элементам тип обтекания - это использование свойства float. Классический пример - использование float для выравнивания картинки по левому или правому краю. Вот простой HTML-код картинки и абзаца:

Lorem ipsum...


Они отображаются с новой строки:

Добавляем немного CSS картинке:
img { float: right; margin: 20px; }

Получается выравнивание по правому краю:

Если текста больше, то абзац будет обтекать картинку:

Допустим, нам нужно сделать отступ в 20 пикселей между картинкой и текстом. Вот такая конструкция работать не будет: p {margin: 20px;}

Правильно вот так:
img {margin: 20px;}

Почему же не работает отступ для абзаца? Чтобы разобраться, добавим рамку:

P { border: solid 1px black; }

Результат может вас удивить:

Оказывается, картинка находится внутри абзаца! Поэтому и не работает свойство margin в первом случае. Чтобы исправить это, можно применить float:left к абзацу и указываем абсолютную ширину:

Странные правила float

Перейдем к более сложным вариантам использования float: к правилам, регулирующим плавающие объекты. Это бывает необходимо при верстке галереи изображений. Например:

По умолчанию каждый элемент списка появится с новой строки. Если применить к каждому float:left, изображения встанут в один ряд с переносом строки:

Li { float: left; margin: 4px; }

Но что, если изображения разной высоты?

Если мы добавим элементам списка отображение в одну строку, получится немного симпатичнее:

Li { display: inline; }

А теперь выравниваем по вертикали:

Img { vertical-align: top; }

Следует помнить, что в случае большей высоты картинок, остальные изображения обтекают только одно предыдущее, например:

Пример изменения очередности элементов - например, у нас есть список элементов по порядку:

Если мы хотим расположить их в обратном порядке, просто применяем float:right вместо float:left, и не придется менять порядок в HTML:

С помощью float удобно группировать элементы на странице, но большой проблемой становится то, что последующие элементы (текст или блок) также получают свойство обтекания. Например, у нас есть блок картинок:

Текст под ним начинает обтекать весь блок:

Чтобы избежать этого, необходимо использовать свойство clear. Если применим его ко второму изображению:

Ul li:nth-child(2) { clear: left; }

Получим вот, что:

В этом случае остальные изображения продолжают наследовать float:left. Соответсвенно текст будет отображаться коряво:

Нужно применить clear:both к абзацу:

P { clear: both; }

Наша проблема решена:

Теперь предположим, что нам необходимо установить фон для галереи из предыдущих примеров. Если бы элементы были не плавающими, то получилось бы вот, что:

Ul { background: gray; }

Но если элементам списка применить float:left, фон совсем пропадает:

Если мы сначала устанавливаем высоту для UL:

Ul { height: 300px; }

Это тоже не решает проблему, т.к. размеры фона заданы абсолютно. Нам поможет класс clearfix, который будет применен к div на том же уровне, что и элементы UL.

Clearfix { clear: both; }

Существует еще одно решение, с использованием overflow:

Ul { overflow: auto; }

Девять правил float-элементов:

  1. Плавающие элементы не могут выходить за край своего контейнера-родителя.
  2. Каждый плавающий элемент будет отображаться справа или ниже от предыдущего при float:left, либо слева и ниже, при float:right.
  3. Блок с float:left не может быть правее, чем блок с float:right.
  4. Плавающий элемент не может выходить за пределы верхней границы своего контейнера.
  5. Плавающий элемент не может располагаться выше, чем родительский блок или предыдущий плавающий элемент.
  6. Плавающий элемент не может располагаться выше, чем предыдущая строка inline-элементов
  7. Плавающий блок должен быть расположен как можно выше.
  8. Один плавающий элемент, следующий за другим, не может выходить за пределы своего контейнера - происходит перенос на следующую строку.
  9. Блок с float:left должен быть расположен как можно левее, а с float:right - как можно правее.

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

Что такое float?

Некоторые элементы в CSS являются блочными и поэтому начинаются с новой строки. Например, если расположить два абзаца с тегами P, то они будут находиться друг под другом. Другие же элементы являются «строчными», т.е. отображаются на странице в одну строку.

Один из способов переназначить элементам тип обтекания - это использование свойства float. Классический пример - использование float для выравнивания картинки по левому или правому краю. Вот простой HTML-код картинки и абзаца:

Lorem ipsum...


Они отображаются с новой строки:

Добавляем немного CSS картинке:
img { float: right; margin: 20px; }

Получается выравнивание по правому краю:

Если текста больше, то абзац будет обтекать картинку:

Допустим, нам нужно сделать отступ в 20 пикселей между картинкой и текстом. Вот такая конструкция работать не будет: p {margin: 20px;}

Правильно вот так:
img {margin: 20px;}

Почему же не работает отступ для абзаца? Чтобы разобраться, добавим рамку:

P { border: solid 1px black; }

Результат может вас удивить:

Оказывается, картинка находится внутри абзаца! Поэтому и не работает свойство margin в первом случае. Чтобы исправить это, можно применить float:left к абзацу и указываем абсолютную ширину:

Странные правила float

Перейдем к более сложным вариантам использования float: к правилам, регулирующим плавающие объекты. Это бывает необходимо при верстке галереи изображений. Например:

По умолчанию каждый элемент списка появится с новой строки. Если применить к каждому float:left, изображения встанут в один ряд с переносом строки:

Li { float: left; margin: 4px; }

Но что, если изображения разной высоты?

Если мы добавим элементам списка отображение в одну строку, получится немного симпатичнее:

Li { display: inline; }

А теперь выравниваем по вертикали:

Img { vertical-align: top; }

Следует помнить, что в случае большей высоты картинок, остальные изображения обтекают только одно предыдущее, например:

Пример изменения очередности элементов - например, у нас есть список элементов по порядку:

Если мы хотим расположить их в обратном порядке, просто применяем float:right вместо float:left, и не придется менять порядок в HTML:

С помощью float удобно группировать элементы на странице, но большой проблемой становится то, что последующие элементы (текст или блок) также получают свойство обтекания. Например, у нас есть блок картинок:

Текст под ним начинает обтекать весь блок:

Чтобы избежать этого, необходимо использовать свойство clear. Если применим его ко второму изображению:

Ul li:nth-child(2) { clear: left; }

Получим вот, что:

В этом случае остальные изображения продолжают наследовать float:left. Соответсвенно текст будет отображаться коряво:

Нужно применить clear:both к абзацу:

P { clear: both; }

Наша проблема решена:

Теперь предположим, что нам необходимо установить фон для галереи из предыдущих примеров. Если бы элементы были не плавающими, то получилось бы вот, что:

Ul { background: gray; }

Но если элементам списка применить float:left, фон совсем пропадает:

Если мы сначала устанавливаем высоту для UL:

Ul { height: 300px; }

Это тоже не решает проблему, т.к. размеры фона заданы абсолютно. Нам поможет класс clearfix, который будет применен к div на том же уровне, что и элементы UL.

Clearfix { clear: both; }

Существует еще одно решение, с использованием overflow:

Ul { overflow: auto; }

Девять правил float-элементов:

  1. Плавающие элементы не могут выходить за край своего контейнера-родителя.
  2. Каждый плавающий элемент будет отображаться справа или ниже от предыдущего при float:left, либо слева и ниже, при float:right.
  3. Блок с float:left не может быть правее, чем блок с float:right.
  4. Плавающий элемент не может выходить за пределы верхней границы своего контейнера.
  5. Плавающий элемент не может располагаться выше, чем родительский блок или предыдущий плавающий элемент.
  6. Плавающий элемент не может располагаться выше, чем предыдущая строка inline-элементов
  7. Плавающий блок должен быть расположен как можно выше.
  8. Один плавающий элемент, следующий за другим, не может выходить за пределы своего контейнера - происходит перенос на следующую строку.
  9. Блок с float:left должен быть расположен как можно левее, а с float:right - как можно правее.

Здравствуйте, уважаемые читатели блога сайт! После весьма существенного перерыва я решил продолжить тему изучения CSS и сегодняшняя статья будет посвящена созданию плавающих элементов посредством float, на практических примерах рассмотрим действие данного правила вкупе со свойством clear для создания колонок и горизонтального меню.

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

Плавающие элементы встречаются также в HTML при необходимости создать обтекание тех же изображений текстом (атрибут align тега img с параметрами left и right). Так что этот аспект весьма популярен при разработке содержания вебстраниц.

На протяжении сегодняшней публикации разберем действия правила float (left, right, none) и clear в том числе применительно к , которые являются основой при блочной верстке. Конечно, на современном этапе подавляющее большинство использует при создании сайта прогрессивные CMS (в частности, WordPress). Однако, поверьте, что знания основ стилей и языка гипертекстовой разметки сослужат вам добрую службу в дальнейшем.

Как создаются плавающие элементы в CSS с помощью float

Для начала напомню, что в нормальном потоке вебэлементы выстраиваются на вебстранице в строгом соответствии с очередностью, которая задается в коде. Однако, как известно, всегда бывают исключения. Это логично, поскольку необходимы рычаги для решения нестандартных задач.

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

Данные по любому свойству (propety) CSS и его значениям можно почерпнуть со страницы спецификации W3C , где дана полновесная информация (данные по второй версии таблиц стилей, но это справедливо и для CSS3, которая уже действует официально, хотя до конца не доработана):


Как видите, float может принимать один из трех возможных параметров (left, right, none) и (inherit). Параметр float none применяется по умолчанию и означает, что элементы будут отображаться в порядке, соответствующем обычному потоку. А вот right или left позволяют создавать плавающие блоки со смещением вправо или влево соответственно.

Если помните, наиболее часто используемые , которые ведут себя по-разному (вообще, тип отображения всех элементов реализуется средствами CSS с помощью свойства Display). Блочные занимают всю доступную ширину, если не указано значение width. Высота определяется содержимым, ежели параметр height не прописан.

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

Для наглядности подключим правила CSS (такой метод на практике обычно редко применяется, но он очень удобен при тестировании).

С тем, чтобы убедиться в правильности выше сказанного, возьмем два строчных тега, прописав для них свойства width и height, а также один блочный тег. С целью обеспечения наглядности зададим цветовые оттенки для каждого блока с помощью background (аналогично можно ):

Строчный элемент 1 Строчный элемент 2

Блочный элемент

Результирующая картинка будет следующей:

Как видите, мы получили практическое подтверждение, что указанные высота (height:50px) и ширина (width:450px) не работают в обычных условиях для тега SPAN, который является строчным. Далее попробуем прописать свойство float right для первого строчного вебэлемента и float left для второго:

Строчный элемент 1 Строчный элемент 2

Блочный элемент

В итоге получаем:


Совершенно очевидно, что в этом случае первый и второй вэбэлементы становятся плавающими (один сместился до упора влево, другой вправо). Дополнительно они приобрели ширину и высоту, которая прописана в CSS стилях.

Более того, вебэлементы, определяемые строчным тегом SPAN, по другому стали взаимодействовать с соседним контейнером DIV. Если далее убрать, скажем, атрибут width из стилей обоих тегов SPAN, то их ширина будет определяться содержанием (в нашем случае длиной текста с названием элементов):

Теперь содержимое блока DIV начинает обтекать справа вэбэлемент с float: left. Есть смысл более наглядно ознакомиться с результатами конкретных практических изысканий на этой вебстранице , где вы можете сами попробовать менять область просмотра и понаблюдать, как поведут себя блоки по отношению друг к другу:


Подытоживая, определим некоторые особенности, которые будут присущи контейнеру с тем или иным значением свойства float (right или left):

  • Элемент смещается к левому или правому краю;
  • Он становится блочным вне зависимости от того, каким он был до этого;
  • Ведет себя таким образом, как будто соседних блочных вэбэлементов (с правилом display:block) не существует. В этом вы можете убедиться, если еще разок взгляните на скриншоты данного раздела статьи;
  • В то же время строчные теги (display:inline) будут обтекать плавающие блоки. Если вновь посмотрите на предыдущий скриншот, то заметите, что содержание DIV контейнера ("Блочный элемент") обтекает SPAN с float:left справа.
  • Если явно не указывать ширину плавающего блока (в нашем примере width:450px), то она будет определена его содержимым;

В данном примере мы рассмотрели основные черты плавающих блоков с разными параметрами свойства float и выбрали для усложнения задачи и строчные, и блочные вебэлементы (с различными значениями Display). В качестве закрепления материала обязательно посмотрите информативный видеоролик от Е.Попова:

Каким образом сделать горизонтального меню посредством CSS (float)

Далее разберем вполне конкретное задание по созданию горизонтального меню с помощью плавающих блоков, которое весьма часто используется при разработке вебсайтов. Сначала сконструируем , код которого будет выглядеть так:

  • Пункт 1
  • Пункт 2
  • Пункт 3
  • Пункт 4
  • Пункт 5
    • Получим примерно следующее:

      Теперь немного подредактируем полученное меню с помощью CSS свойств: уберем маркеры напротив каждого из пункта при помощи list-style none, преобразуем строчные в блочные, применив к ним правило display block, а также для разнообразия придадим каждой из них приятный фон.

      Также нелишним будет задать отступы margin, чтобы еще более улучшить дизайн, немного отодвинув пункты меню друг от друга. Для вебстраниц сайта WordPress можно задать тегу UL "menu", для которого указать необходимые стили в файле STYLE.CSS:

      Menu {list-style:none;margin:0;padding:15px;} .menu li a{display:block;padding:10px;background:#EFCDB8;} .menu li{margin:10px;}

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


      Разница с предыдущим вариантом разительная, не правда ли? Теперь мы получили картинку, которая гораздо больше напоминает классическое меню. Правда, пункты в нем расположены не горизонтально, а вертикально. Для полного решения задачи нужно дописать для элемента HTML списка LI свойство float left, полностью правило CSS для него станет таким:

      Menu li{margin:10px;float:left;}

      В итоге менюшка превратиться в горизонтальный вариант:


      Думаю, на основании выше предоставленной информации вам понятна причина, по которой произошла такая метаморфоза. Каждый вебэлемент меню с float left ориентируется на расположение контейнера, его границы и пытается занять место, сдвинувшись максимально вверх-влево. Так и случилось с блоком «Пункт 1», который расположился соответствующим образом.

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

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

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

      Тогда «Пункт 3» будет выравнивать свое положение по нижней границе последнего вэбэлемента в верхнем ряду и только потом переедет влево. Все описанные выше телодвижения должны помочь вам осмыслить суть воздействия float на расположение вебэлементов страницы.

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

      Эффект применения свойства clear (both, left, right)

      Теперь посмотрим, как использовать на свое благо особенности плавающих элементов, но одновременно заставить ниже следующие блоки на вебстранице учитывать их положение и размеры. Этого можно добиться с помощью правила clear. Опять же всю информацию можно получить от первоисточника (консорциума W3C):


      Правило CSS clear имеет четыре возможных значения , причем property none является параметром по умолчанию, что вполне естественно, поскольку в этом случае обеспечивается стандартный поток кода. Также clear (none, left, right, both) наследуется от родительского тега (inherit).

      Суть этого правила, прописанного для определенного блока, заключается в отмене действия в зависимости от его значения:

      • none - отменяет действие самого свойства clear, в результате содержание тега (например, текст) обтекает вэбэлемент в соответствии с заданными ему стилями в виде float;
      • left и right - ликвидирует обтекание соответственно с левого либо правого края;
      • both - препятствует обтеканию одновременно справа и слева. Это самый распространенное значение clear в практическом использовании.

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

      Итак, возьмем два контейнера DIV, которые схематически могут представлять из себя 2 колонки. Пропишем для них CSS свойства, включая фиксированную ширину (width), цвет фона и превратив их в плавающие с помощью float left. Добавим к ним текст, заключенный в тег P, который, как известно, является строчным:

      Левая колонка
      Правая колонка

      Блоки DIV выстроятся в горизонтальный ряд, причем первый займет крайнее левое положение, насколько это возможно. А второй припаркуется к его правому краю (для него это будет расположение слева), дальше не позволит сдвинуться первый див. А вот текст продолжит этот ряд, так как общая ширина позволяет это сделать:

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


      Опять же можете сами посмотреть , как поведут себя все элементы, искусственно сужая-расширяя область просмотра. Чтобы устранить описанные недостатки, добавим контейнер со свойствами CSS и поместим внутрь его все имеющиеся слои. А также добавим дополнительно пустой DIV с правилом CSS clear both, чтобы запретить обтекание содержанием нижнего блока (текстом) колонок справа и слева:

      Левая колонка
      Правая колонка

      Обратите внимание, что к стилям большого дива я добавил правило margin:0 auto , с помощью которого можно выровнять контейнер по центру. Результирующий вид будет таковым:


      Теперь наша задача решена, поскольку итог соответствует поставленным условиям: две колонки расположены в горизонтальном ряду, а содержание ниже стоящего в коде вэбэлемента (ТЕКСТ) будет жестко оставаться на своем законном месте под колонками.

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



Есть вопросы?

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: