float
на практикеНа этой странице:
Сначала рассмотрим пример использования свойства float
по
прямому назначению — для создания блоков, которые другие
элементы страницы обтекают слева или справа, а затем посмотрим, как можно
использовать плавающие блоки для построения горизонтального меню
и многоколонной вёрстки страниц.
Отметим, что свойство float
не предназначено для
вёрстки колонок, хотя используется для этой цели очень часто. Но что
делать, если настоящие средства многоколонной вёрстки присутствуют
только в стандарте CSS3 (серия свойств с префиксом column
),
который браузеры пока не поддерживают. Вот и приходится разработчикам
придумывать техники, основываясь на подручном материале.
Врезка в виде плавающего блока создаётся просто и естественно —
именно для таких целей и было задумано свойство float
.
Врезка размещается в блоке
Фокус с |
Код HTML (с сокращениями):
<BODY>
<H1>Роботландия</H1>
<DIV id="incut">
<H2>Роботландский конь</H2>
...
</DIV>
<P>
Курс с таким названием вошёл...
<P>
...
<DIV id="footer">...</DIV>
</BODY>
Код CSS (с сокращениями):
#incut
{
float:right;
width:15em;
padding:10px;
margin:0 0 10px 10px;
border:1px solid #638F7B;
background:#fff2a6;
font-family:"Trebuchet MS",sans-serif;
}
|
Используя свойство float
, построим горизонтальное меню.
В настоящем меню пункты должны быть ссылками на
страницы сайта, но в этом примере мы не будем отвлекаться на
организацию гипертекстовых переходов.
Вот так это выглядит в окне браузера. На горизонтальное меню совсем не похоже, но стоит взять в руки CSS… |
Меню — это список. Поэтому логично записать его
в виде <UL class="menu"> <LI>Начало <LI>Продукты <LI>Университет <LI>Ссылки <LI>Автор </UL> |
Так это выглядит в FireFox и Opera.
Так — в IE.
Благодаря
Однако налицо две проблемы: появилась горизонтальная прокрутка, и
фон, заданный для |
Сформулируем правила CSS, которые превращают вертикальный список в горизонтальный:
.menu
{
width:100%;
margin:0;
padding:6px;
list-style:none; /* Убираем маркеры */
background:#ffcb2d;
}
.menu LI
{
float:left;
display:inline; /* Уловка для IE */
margin-left:1em;
font-family:Arial, sans-serif;
font-size:70%;
}
|
С прокруткой всё понятно. Мы указали 100% для ширины блока
UL
. Но это ширина без отступов и границ. Значит,
общая ширина UL
получается равной
100% + 12 пикселов (6 пикселов, заданные в padding
с обеих сторон). То есть ширина UL
больше ширины BODY
на 12 пикселов —
вот и включается прокрутка.
Вывод: если для блока определена ширина в 100%, нельзя для него задавать горизонтальные отступы и границу.
В нашем случае надо положить padding:0
(в дополнение
к margin:0
).
Но почему фон, заданный для UL
, не
охватывает элементы LI
в браузерах
FireFox и Opera?
На самом деле, эти браузеры ведут себя согласно стандартам, а ошибается как раз IE!
Блок UL
находится в потоке, а его потомки
LI
удалены из потока свойством
float:left
. Блок UL
оказался пустым.
Мы бы вообще его не увидели, если бы не padding:6px
.
Вот эти 12 пикселов (6 сверху плюс 6 снизу), окрашенные в цвет фона,
мы и видим по вертикали (ссылка).
Благодаря
Отказ от горизонтальных отступов |
Добавим в правила для блока .menu { float:left; width:100%; margin:0; padding:6px 0; list-style:none; /* Убираем маркеры */ background:#ffcb2d; } |
Рассмотрим типичный макет страницы с заголовочной частью, двумя колонками и подвалом:
|
HTML-код: <BODY> <H1></H1> <DIV id="content"></DIV> <DIV id="sidebar"></DIV> <DIV id="footer"></DIV> </BODY> |
Зафиксируем для BODY
такую ширину,
чтобы страница отображалась без горизонтальной прокрутки
в окнах шириной 800 пикселов.
Блоки H1
и footer
оставим в потоке, а колонки
(блоки content
и sidebar
) сделаем плавающими.
Не забудем при этом для блока footer
указать свойство
clear:both
, чтобы прекратить обтекание и обеспечить расположение
подвала ниже обеих колонок.
Для
Общая ширина
Общая ширина |
Самое главное — аккуратно указать числовые значения ширины для всех блоков и не забыть про отличие коробочной модели IE (ссылка).
Определимся с общей шириной
Проверка: 740 (ширина содержимого |
Теперь нетрудно написать стилевые определения:
HTML { text-align:center; /* Центрирование BODY для IE5 */ background:#F6F2E4; } BODY { /* Раскладка */ margin:10px auto; /* BODY по центру HTML */ text-align: left; /* Выравнивание текста слева */ padding:10px; border:1px solid #638F7B; width:740px; /* Для старых хороших браузеров */ \width:762px; /* Обман для IE5 */ w\idth:740px; /* Для новых хороших браузеров */ /* Шрифты */ font:small Georgia, serif; /* Цвета */ color:black; background:white; } /* Заголовочная часть*/ H1 { } /* Общие свойства блока содержания и боковой панели */ #content, #sidebar { color:#2A3D34; padding:10px; } /* Содержание */ #content { float:left; background:#d4dff3; width:480px; /* Для старых хороших браузеров */ \width:500px; /* Обман для IE5 */ w\idth:480px; /* Для новых хороших браузеров */ } /* Боковая панель*/ #sidebar { float:left; background:#fff2a6; width:220px; /* Для старых хороших браузеров */ \width:240px; /* Обман для IE5 */ w\idth:220px; /* Для новых хороших браузеров */ } /* Подвал */ #footer { clear:both; padding:0 10px 10px 10px; white-space:nowrap; }
Для блока sizebar
задано float:left
,
но можно было бы задать и float:right
—
в данном случае нет никакой разницы.
|
Получилось неплохо, кроме одной неприятности: на колонки это совсем не похоже. Колонки по определению должны иметь одинаковую высоту! Проблема имеет решение под названием «ложные колонки» (ссылка). |
|
Суть метода в следующем: для контейнера колонок задаётся фоновая полоска, которая замащивает блок по вертикали, «продлевая» тем самым, высоту колонок до конца контейнера. Высоты колонок, конечно, остаются прежними, но визуально они уравниваются. |
В нашем случае контейнером колонок является блок BODY
,
что неудовлетворительно. Ведь если замостить BODY
ложными колонками, в них попадут блоки header
и
footer
, что совершенно не нужно.
Придётся колонки обернуть во вспомогательный блок
wrapper
(он станет контейнером колонок) и именно для него
указать нужную фоновую полоску.
Вероятно, вы догадались, зачем блок Если оставить блок в потоке, фоновой полоски мы не увидим, ведь блок окажется пустым (его плавающие потомки не в счёт), значит, высота его равна нулю (ссылка). |
Изменения в HTML: <BODY> <H1></H1> <DIV id="wrapper"> <DIV id="content"></DIV> <DIV id="sidebar"></DIV> </DIV> <DIV id="footer"></DIV> </BODY> Изменения в CSS: /* Обёртка блоков sidebar и content */ #wrapper { float:left; background:url(pic/bg.png) repeat-y; } |
Понятно, что показанная методика работает при любом числе
колонок. Для всех плавающих блоков задаём float:left
,
и они будут прилипать друг к другу слева на одной горизонтали.
Самое главное — аккуратно задать размеры всем блокам так, чтобы
сумма равнялась ширине области содержимого
BODY
(значению его свойства width
).
Сделаем обе колонки «резиновыми». Пусть они заполняют ширину текущего окна в отношении 70%:30%.
|
HTML-код: <BODY> <H1></H1> <DIV id="wrapper"> <DIV id="content"> <DIV class="wrap"></DIV> </DIV> <DIV id="sidebar"> <DIV class="wrap"></DIV> </DIV> </DIV> <DIV id="footer"></DIV> </BODY> |
Блоки content
и sidebar
, как и ранее, обёрнуты
контейнером wrapper
с той же целью: создать ложные
колонки в виде фона блока wrapper
.
Кроме того, содержимое блоков content
и sidebar
погружено в блоки <DIV class="wrap"></DIV>
. Зачем?
Так сделано потому, что мы не можем в этом макете задавать отступы
(и границу) для блоков content
и sidebar
,
как это делали в макете с фиксированной шириной колонок.
Пусть для
|
В самом деле, мы должны указать: #content { float: left; width: 70%; } #sidebar { float: left; width: 30%; } Если задать ещё и отступы, то они добавятся к общей ширине блоков, и сумма превысит ширину контейнера.
Поэтому блокам |
С учётом сказанного, записываем стилевые определения для нашего «резинового» макета:
BODY { /* Раскладка */ margin: 10px; padding: 0; /* Шрифты */ font: small Georgia, serif; /* Цвета */ color: black; background: white; } /* Заголовочная часть*/ H1 { } /* Обёртка блоков content и sidebar*/ #wrapper { float: left; width: 100%; } /* Общие свойства боковой панели и содержания */ #sidebar, #content { color: #2A3D34; } /* Отступы для содержимого блоков sidebar и content */ .wrap { padding:10px; } /* Содержание */ #content { float: left; width: 70%; background: #d4dff3; } /* Боковая панель*/ #sidebar { float: left; width: 30%; background:#fff2a6; } /* Подвал */ #footer { clear: both; padding: 0 10px 10px 10px; }
|
Отметим две неприятности, связанные с браузером IE. Первая связана с тем, что IE не умеет считать.
Предположим, ширина блока |
|
Пусть теперь ширина блока Неприятности можно избежать, если для второго блока задать ширину, равную не 30%, а только 29.9%. Существуют и другие решения, одно из них описано в заметке Владимира Токмакова «Борьба с прыгающими блоками в IE» (ссылка). Это решение рекомендуется к использованию в практикуме 2 к этому разделу и проекте 4 темы 2. Оно также использовано в кодах примера 2. |
Вторая неприятность связана с тем, что в узких окнах разметка рушится:
блоки начинают наползать друг на друга, а в IE блок sidebar
опять скачет вниз.
Для нормальных браузеров решение очень простое — нужно задать
для BODY
свойство min-width
.
Для IE приходится идти на хитрости при помощи функции
expression
, которую понимает только IE (IE7 уже научили понимать свойства
min-width
и max-width
).
Таким образом, получаем следующие правки в стилевых определениях:
BODY { /* Раскладка */ margin: 10px; padding: 0; min-width: 640px; width: expression(documentElement.clientWidth < 700 ? '700px' : 'auto'); /* Шрифты */ font: small Georgia, serif; /* Цвета */ color: black; background: white; } /* Содержание */ #content { float: left; width: 70%; background: #d4dff3; } /* Боковая панель*/ #sidebar { float: left; width: 29.9%; background:#fff2a6; }
Значения 700px
для IE и 640px
для
других браузеров подобраны экспериментальным путём.
В IE был установлен самый крупный шрифт (в меню
Вид/Размер шрифта
), затем уменьшалась ширина окна,
пока блок sidebar
не стал сваливаться вниз.
Займёмся теперь фоновой полоской, создающей ложные колонки.
Суть метода в особенностях вывода фоновой картинки, положение которой задано в процентах (ссылка). |
Общая длина фоновой полоски делается настолько большой, например, 3000 пикселов, чтобы она смогла покрыть ширину окна на огромном мониторе.
Полоска делится разными цветами в таком же процентном отношении, что и наши
колонки ( |
Для вывода полоски используется стилевое правило:
/* Обёртка блоков sidebar и content */ #wrapper { background:url(pic/bg.png) 70% top repeat-y; }
Две вертикали, одна на элементе, другая на картинке, проведённые в
70% от левого края (соответственно, элемента и картинки), будут
совпадать при любой ширине элемента wrapper
.
Это как раз то поведение, которое нам нужно для создания ложных колонок.
|
Окончательный вариант макета показан на рисунке, но важно посмотреть, как страница ведёт себя при изменении ширины окна браузера. Загрузите макет и проверьте его работу в окнах разной ширины. |
|
Описанный метод легко обобщить на любое число колонок.
Например, для трёх колонок задаём два обёрточных блока
и две фоновые картинки:
первую для блока |