float
На этой странице:
Формальное описание свойства
Однако, алгоритм работы свойства |
|
|
CSS-cвойство
Картинка (элемент |
Рассмотрим в деталях поведение элемента с заданным для него свойством
float
, но прежде введём два определения.
Назовём контейнером первый предок элемента в иерархическом дереве элементов, который является блоком.
Строчный элемент |
В качестве примера рассмотрим код: <BODY> <DIV> <P> В этом абзаце внутри <STRONG>сильного выделения находится обычное <EM>выделение</EM></STRONG>. </P> </DIV> </BODY>
Контейнером элемента |
Будем называть элемент с заданным свойством
float:left
или float:right
плавающим элементом (в ходу ещё один термин:
перемещаемый элемент).
Плавающий элемент автоматически становится блоком, даже если он был строчным элементом.
Элемент
Как вы помните (ссылка), внешние отступы
строчных элементов работают только по горизонтали. Здесь свойство
Плавающий элемент прижимается к своему контейнеру внешним краем своего внешнего отступа, вот почему мы видим зазор у левой границы. Подробнее об этом в следующем пункте. |
HTML-код:
<P>
В этом предложении внутри
<STRONG>сильного выделения
находится обычное
<EM>выделение</EM></STRONG>.
Это второе предложение, оно
завершает абзац.
</P>
CSS-код:
EM
{
float:left;
background:#fff2a6;
padding:10px;
margin:10px;
border: 1px solid black;
}
|
Практический вывод: если для строчных элементов (таких, как
EM
,
STRONG
,
CITE
,
DFN
,
A
,
IMG
,
SPAN
и других) задаётся свойство
float:left
или float:right
, то для них
автоматически устанавливается свойство display:block
, и
нет необходимости в явной установке этого свойства.
Более того, если мы даже укажем для плавающего элемента
свойство display:inline
, оно будет проигнорировано.
Плавающий элемент со значением left
прижимается к
левому краю, а плавающий элемент со значением right
—
к правому краю своего контейнера.
Все элементы имеют внешние и внутренние отступы, а также границу. Возникает вопрос: какой именно частью плавающий элемент прижимается к своему контейнеру? И к какой именно части контейнера?
Действует правило:
Плавающий элемент примыкает к внутреннему краю своего контейнера своим внешним краем.
Плавающий элемент может выйти за пределы своего контейнера только в том случае, если для него (плавающего элемента) задан отрицательный внешний отступ. |
То есть внешний край внешнего отступа плавающего элемента соприкасается с внутренним краем внутреннего отступа контейнера. Или, что тоже самое: внешний край внешнего отступа плавающего элемента соприкасается с краем области содержимого своего контейнера (см. описание коробочной модели элемента). Такое поведение означает, что плавающий элемент не может выйти за пределы области содержимого своего контейнера.
Так будет всегда, если только для плавающего
элемента не задан отрицательный |
Положение верха плавающего элемента определяется по более сложному алгоритму и зависит от того, был элемент строчным или блочным до того, как стал плавающим.
Сначала исследуем поведение плавающего элемента, который был блочным. Пусть страница задана следующим кодом.
HTML-код:
<BODY>
<P>Первый абзац. Он расположен в коде до плавающего элемента.
<P class=float>Второй абзац. Это плавающий элемент.
<P>Третий абзац. Он расположен в коде после плавающего элемента.
<P>Четвёртый абзац. Он расположен в коде последним.
</BODY>
CSS-код:
BODY { padding:0; margin:0;}
P /* Правила для всех абзацев */
{
background:cyan;
padding:10px;
margin:10px;
border: 1px solid black;
}
P.float /* Дополнения для абзаца float */
{
float:left;
width:160px;
background:#fff2a6;
}
Заметим, что в горизонтальном направлении плавающий блок внешней
частью своего внешнего отступа точно примыкает к границе области
содержимого своего контейнера |
Верх плавающего элемента занимает такое место, которое оно имело бы в потоке, за исключением одного момента: внешние отступы плавающего элемента не схлопываются (ссылка). Видим на иллюстрации, что расстояние от границы плавающего блока до границы первого абзаца равно не 10 пикселов, а 20. Внешний отступ первого абзаца (10 пикселов) сложился с внешним отступом плавающего блока (10 пикселов). |
В этом месте придётся остановиться, чтобы сделать замечание IE.
Выше уже отмечалось, что указание |
Так отображается, приведённый выше код, в самом популярном на сегодня браузере Интернета.
Видим, что внешний отступ слева удваивается (у плавающих элементов
с
К счастью, этот баг излечивается очень просто — если для плавающего
элемента записать |
Рассмотрим поведение плавающего элемента, который был строчным.
Стандарт формулирует здесь два правила.
Первое правило. Если плавающий элемент создан из строчного элемента, его верх (верх его внешнего отступа) не может подниматься выше верха той строки, в которой он находился бы в обычном состоянии.
Второе правило. Плавающий элемент должен располагаться максимально высоко, не нарушая при этом первое правило.
|
Таким образом, если элемент находится в первой строке, то верх образованного из него плавающего элемента должен совпадать с верхом первой строки. Так и происходит на практике. |
Рассмотрим теперь поведение элемента, расположенного не в первой строке.
|
Пусть в потоке строчный элемент располагается во второй строке. Из правил следует поведение, представленное на следующей иллюстрации. |
|
Если строчный элемент стал плавающим, eго верх должен совпадать с верхом строки в которой он ранее находился. |
|
На практике браузеры, либо всегда выводят плавающий элемент на строку ниже (IE, FireFox), либо и так, и так, в зависимости от того, есть ли в текущей строке место (Opera). |
Путь страница задана следующим кодом.
HTML-код:
<BODY>
<P>
В этом предложении внутри <STRONG>сильного выделения находится
обычное <EM>выделение</EM></STRONG>. Это второе предложение, оно
завершает абзац.
</P>
</BODY>
CSS-код:
BODY { margin:0; padding:0; }
P { margin:0; padding:0; background:cyan; }
EM
{
float:left;
margin:0; padding:10px;
width:100px;
background:#fff2a6;
border: 1px solid black;
}
|
По правилам верх плавающего элемента должен располагаться во второй строке, но все браузеры располагают его в третьей. |
|
Opera может вывести элемент и во вторую строку. |
Всё выше сказанное относится к элементам с нулевыми и положительными
внешними отступами. Отрицательные значения margin-top
заставляют элемент подниматься выше обычного положения и даже перекрывать
расположенные там элементы.
Изымается ли плавающий элемент из потока? Да, конечно.
Если элемент был блочным, он перестаёт занимать всю ширину родителя (что свойственно блокам в потоке), для него перестаёт действовать правило схлопывания внешних отступов.
Если элемент был строчным, он превращается в блок и покидает своё строчное место (удаляется из строки).
Плавающий элемент располагается над потоком, но не перекрывает содержимое (хотя перекрывает фон блоков в потоке). |
Плавающий элемент поднимается над потоком. Он смещается по горизонтали к краю области содержимого своего контейнера. Блоки, следующие за ним, подтягиваются вверх и занимают освободившееся место в потоке. Однако плавающий элемент не перекрывает содержимое других блоков. Содержимое начинает обтекать плавающий блок со свободной стороны. |
Плавающий блок прижимается к границе контейнера, а элементы потока
обтекают его. На практике часто бывает необходимо прекратить
обтекание в каком-то месте потока, чтобы начать, например,
новый раздел. Для
прекращения обтекания используют свойство |
|
Блок, в котором задано свойство |
Свойство
Свойство
Значение |
|
Плавающие блоки не перекрывают друг друга и не перекрывают содержимое потока (если только у них не заданы отрицательные внешние отступы). Пусть плавающий блок 1 идёт в коде раньше плавающего блока 2. Блок 2 не может занимать на экране положение выше блока 1, но располагается максимально высоко. |
|
Если плавающие блоки с однотипным указанием
( |
|
Если места нет, плавающий блок, идущий в коде дальше, смещается ниже. |
|
Следующие в коде друг за другом плавающие блоки разного типа
|
|
Если места нет, блок, который в коде идёт дальше, смещается ниже. |
|
Пусть в потоке один блок вложен в другой: <DIV id="block1"> <DIV id="block2"> ... </DIV> </DIV> |
Никакой странности нет. Плавающий блок покинул поток, и его родитель оказался пустым. |
Сделаем вложенный блок плавающим: #block2 {float:left} Видим “странную” картину: блок-родитель “схлопнулся” по вертикали до размеров своих рамок и отступов. |
Плавающий элемент не выходит за пределы своего плавающего родителя (если только не заданы отрицательные внешние отступы). |
Довольно часто разработчику нужно, чтобы плавающий блок остался в пределах своего родителя. Для этого достаточно блок родителя тоже сделать плавающим: #block1 {float:left} #block2 {float:left} |
Рассмотрены самые важные правила поведения плавающих блоков, теперь можно перейти к практической части.