Плавающая модель в теории вещь крайне простая и понятная. В CSS существует возможность создавать блоки, которые будут не следовать друг за другом, как в нормальном потоке, а прилипать к краю контейнера, выстраиваясь в колонки.
При плавающей модели блок вырывается из нормального потока и смещается максимально вверх и влево (или вправо). Получается, что если, скажем, создать три блока, суммарная ширина которых не превышает 100%, то получится три колонки.
Для объявления блока плавающим имеется свойство float, которое может принимать значения left и right. Как вы догадываетесь, значения определяют сторону, к которой блоки будут прилипать. Сразу небольшой пример для наглядности. Создадим три блока с толстой рамкой, которые образуют колонки на основе плавающей модели:
DIV {border: 3px solid #DDD; margin: 3px}
#menu {width: 20%; float: left}
#main {width: 40%; float: left}
#news {width: 25%; float: left}
. . .
<div id="menu">меню</div>
<div id="main">текст</div>
<div id="news">новости</div>
Плавающая модель выглядит вполне привлекательно. Пока возникает один вопрос, как сделать так, чтобы блок переносился под все остальные? Это как раз та ситуация, на которой мы споткнулись при абсолютном позиционировании. В плавающей модели есть свойство clear, которое позволяет располагать блок ниже всех плавающих блоков. Свойство clear принимает следующие значения:
left: блок перемещается ниже всех плавающих блоков с объявлением float: left
right: блок перемещается ниже всех плавающих блоков с объявлением float: right
both: блок перемещается ниже всех плавающих блоков
Давайте дополним наш пример таким блоком.
#copy {width: 90%; clear: left}
. . .
<div id="menu">меню</div>
<div id="main">текст<br><br><br></div>
<div id="news">новости</div>
<div id="copy">копирайт</div>
В блок main я вставил несколько переводов строк, чтобы увеличить его высоту. Для теста так можно делать. В результате блок copy будет расположен ниже всех остальных блоков.
При создании плавающих блоков есть только одно важное правило:
ПРАВИЛО
Для плавающих блоков надо всегда задавать ширину, потому что в противном случае блок будет растягиваться, чтобы вместить в себя все содержимое.
Раз уж плавающая модель оказалась простой понятной, давайте попробуем применить ее к нашему многострадальному примеру. Как и раньше, будем пользоваться правильной блоковой моделью, то есть код адаптирован для браузеров Mozilla и Opera. Позже я покажу, как внести в код кросс-браузерность. За основу будем брать код, который был написан при попытке сверстать макет на основе абсолютного позиционирования.
Как обычно, начнем с шапки. Сам HTML-код совершенно не изменится: все те же блоки с логотипом и т.п. Но зато поменяется CSS-код. Для двух верхних блоков он станет вот таким:
#top-left {
width: 487px;
background: url(i/bd.gif) repeat-x 0px 49px;
padding-left: 30px;
float: left}
#top-right {
width: 233px;
padding-top: 49px;
float: left}
В блоке top-left появилось только одно объявление, которое делает блок плавающим, и исчезло объявление высоты блока. Оказывается, что высота блока в данном случаен ни на что не влияет. В блоке top-right я убрал все свойства абсолютного позиционирования и тоже включил для блока плавающую модель. Но раньше мы задавали смещение от верхнего края, а у плавающей модели такого свойства нет. Значит смещение надо реализовать другим способом. Обычно смещение можно сделать с помощью отступа, в данном случае верхнего padding-top.
После таких изменений два верхних блока будут в браузере выглядеть совершенно так же, как при абсолютном позиционировании, то есть правильно. Далее между верхними блоками и центральными блоками имеется пространство. Для того, чтобы быть уверенным в том, что центральные блоки начнутся после верхних блоков, не помешает создать блок со свойством clear. Заодно он будет отбивать блоки:
.space {clear: left; height: 20px}
В HTML-коде блок с классом space будет находится между верхними и центральными блоками:
Давайте быстро разберемся с центральными блоками. HTML-код для них тоже не изменится, а стили станут вот такими:
#main-left {
width: 125px;
float: left}
#main {
width: 364px;
padding: 0px 14px;
float: left}
#main-right {
font: 10px Verdana;
width: 233px;
float: left}
Свойства абсолютного позиционирования заменены на свойства плавающей модели. Кроме того, опять возникает необходимость сделать отступы между центральным блоком и двумя крайними. Проще всего задать левый и правый отступы только для центрального блока, что и сделано объявлением padding: 0px 14px.
Как видите, в целом можно заметить, что CSS-код для плавающей модели компактнее, чем для абсолютного позиционирования.
Сейчас как раз настал момент, когда можно отлично заметить, для чего необходимо свойство clear. Давайте не будем вставлять блок с таким свойством между центральными блоками и нижним блоком. Блок bottom-left сделаем плавающим:
#bottom-left {width: 233px; float: left}
Блок bottom-left позиционируется совершенно правильно. Он смещается максимально вверх и прилипает к другому плавающему блоку main. Так и должен себя вести любой приличный плавающий блок. Но нам такого не надо, нам надо расположить нижний блок под всеми остальными. Поэтому в HTML-коде после всех центральных блоков мы вставляем блок с классом space.
Осталось только сделать блок с копирайтом:
#bottom-right {
background: url(i/bd.gif) repeat-x;
font: 10px Verdana;
width: 237px;
padding-left: 280px;
float: left}
Используем черную точку для создания фоновой черной линии, затем задаем шрифт для копирайта, устанавливаем ширину и большой левый отступ, чтобы правильно позиционировать текст внутри блока. В итоге в браузере Mozilla макет выглядит отлично. Ура, можно наливать шампанское!
Давайте, правда, шампанским немного повременим, потому что впереди у нас адаптация кода для браузера Internet Explorer. Нам надо исправлять блоковую модель, а точнее, задавать для данного браузера другие значения свойств width там, где используются отступы. Таких блоков у нас всего три: top-left, main и bottom-right. Еще раз сформулирую задачу: для браузера Internet Explorer необходимо установить ширину с учетом отступов, а для всех остальных браузеров оставить текущие значения ширины. То есть нам пригодится решение, которое позволяет разделить код для двух таких типов браузеров. Решение, к счастью, есть. Если заключить значение свойства в кавычки, то его не будут воспринимать браузеры Mozilla и Opera. Например, если мы напишем:
A {border: "1px solid #000"}
То рамки вокруг ссылок сделает только браузер Internet Explorer. В нашем случае нечто подобное надо сотворить с шириной. Давайте подумаем. Начнем думать на примере блока main:
#main {
width: 364px;
padding: 0px 14px;
float: left}
Сначала посчитаем, какую ширину надо задать для браузера Internet Explorer. Раз ширина содержания 364 пикселя, а ширина отступов (левого и правого) 28 пикселей, то ширина должны быть 264+28=392 пикселя. Отлично, делаем следующее. Для браузера Mozilla оставляем первым текущее объявление ширины. А сразу вслед за ним вставляем объявление ширины для браузера Internet Explorer, но заключенное в кавычки!
#main {
width: 364px; width: "392px";
padding: 0px 14px;
float: left}
В итоге получается, что браузер Mozilla прочитает первое значение, но проигнорирует второе. А браузер Internet Explorer прочитает и первое, и второе значения, но значение, указанное в коде позже, переписывает первое значение! Вот таким простым, с одной стороны, но весьма элегантным способом решается проблема блоковой модели. Конечно, способов множество, но это наиболее эффективный. Совершенно аналогичным образом добавляем объявления для остальных двух блоков:
#top-left {
background: url(i/bd.gif) repeat-x 0px 49px;
width: 487px; width: "517px";
padding-left: 30px;
float: left}
#bottom-right {
background: url(i/bd.gif) repeat-x;
font: 10px Verdana;
width: 237px; width: "517px";
padding-left: 280px;
float: left}
Все, после этого вид макета во всех браузерах правильный, и уж точно можно открывать шампанское (у вас в холодильнике обязательно должна лежать бутылочка для подобных моментов).
Наверное, многие из вас с удивлением обнаружат, что вес документа изменился незначительно. Действительно, достаточно часто заявляется, что применение стилей значительно сокращает размер кода. Однако в нашем случае правило не сработало. Отчасти это связано с тем, что макет достаточно простой, но все же обычно экономия не бывает очень большой.
За счет чего же плавающая модель выигрывает по сравнению с табличной версткой? Самое главное преимущество – уменьшение сложности и повышение логичности. Значительно сократилось использование картинок и очень сильно упростился чистый HTML-код. Да, добавились стили, которые сами по себе не являются простыми, но произошло качественное разделение структуры и представления документа. Теперь HTML-код описывает структуру, а CSS-код – представление. Сразу скажу, что разделение не стопроцентное, но очень даже значительное.