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.
Это как раз то поведение, которое нам нужно для создания ложных колонок.
|
|
Окончательный вариант макета показан на рисунке, но важно посмотреть, как страница ведёт себя при изменении ширины окна браузера. Загрузите макет и проверьте его работу в окнах разной ширины. |
|
|
Описанный метод легко обобщить на любое число колонок.
Например, для трёх колонок задаём два обёрточных блока
и две фоновые картинки:
первую для блока |