Позиционирование блоков. Абсолютное и относительное позиционирование. Плавающие и фиксированные блоки.
Позиционирование блоков
В HTML для позиционирования элементов на странице мы использовали таблицы. У таблиц есть как преимущества (легкость использования, одинаковое отображение браузерами), так и недостатки (объемный, нечитабельный код, нелогичность верстки и т.д.).
В CSS для позиционирования элементов используются блоки (div-ы). Код при этом становится компактным, логичным и легко изменяемым. К недостаткам блочной верстки можно отнести неодинаковую поддержку браузерами, поэтому приходится писать кроссбраузерный код (т.е. код, который отображается разными браузерами почти одинаково).
Итак, приступим. Предположим, у нас есть вот такая стандартная html-страница:
Эту страницу мы с вами делали в серии уроков, посвященных HTML, где мы и верстали ее с помощью таблицы. Эта страница имела следующий код:
<html>
<head>
<title>CSS позиционирование</title>
</head>
<body>
<table width="715" border="1"
align="center" cellspacing="0" cellpadding="10">
<tr bgcolor="darkred">
<td colspan="2" height="100">шапка сайта</td>
</tr>
<tr bgcolor="oldlace">
<td width="190" height="300">меню</td>
<td>контент</td>
</tr>
<tr bgcolor="darkred">
<td colspan="2" height="30">низ сайта</td>
</tr>
</table>
</body>
</html>
Теперь давайте посмотрим, как можно сверстать такую страницу средствами CSS.
Если визуально разделить нашу страницу на прямоугольные блоки, то мы получим четыре блока: шапка сайта, меню, контент и низ сайта. Таким образом, мы имеем четыре div-а.
Давайте напишем html-код страницы с четырьмя div-ами и каждому дадим соответствующий идентификатор (id):
<html>
<head>
<title>CSS позиционирование</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id="header">шапка сайта</div>
<div id="menu">меню</div>
<div id="content">контент</div>
<div id="footer">низ сайта</div>
</body>
</html>
Теперь, на странице style.css зададим те свойства, которые уже знаем, а именно ширину, высоту и фон каждого блока:
#header{
background:darkred;
width:715px;
height:100px;
}
#menu{
background:oldlace;
width:190px;
height:300px;
}
#content{
background:oldlace;
width:525px;
height:300px;
}
#footer{
background:darkred;
width:715px;
height:30px;
}
Сейчас наша страница в браузере (в уменьшенном варианте) выглядит так:
Такое позиционирование элементов называется позиционированием в нормальном потоке. Это значит, что все элементы отображаются в окне браузера сверху вниз, по вертикали, в том порядке, в каком они следуют друг за другом в html-коде.
По своей сути нормальный поток ничем не отличается от позиционирования элементов в HTML. И для верстки такой страницы без CSS, нам пришлось бы использовать таблицу, за неимением других вариантов.
В CSS же нам предоставляются и другие схемы позиционирования:
- абсолютное позиционирование
- относительное позиционирование
- плавающая блоковая модель
Для определения схемы позиционирования используется свойство position, оно может принимать четыре значения, соответствующие выбранной схеме позиционирования:
- static - блок позиционируется в нормальном потоке. Это значение по умолчанию.
- relative - относительное позиционирование (относительно нормального потока).
- absolute - абсолютное позиционирование
- fixed - фиксированное позиционирование (фиксируется относительно области просмотра).
Абсолютное позиционирование
При этой схеме позиционирования расположение блока на странице не зависит от того, в каком месте html-кода расположен этот блок. Расположение каждого блока задается указанием, в каком месте экрана отобразить данный блок. Для этого существуют четыре свойства:
- left - указывает на сколько надо сместить блок относительно левого края окна.
- right - указывает на сколько надо сместить блок относительно правого края окна.
- top - указывает на сколько надо сместить блок относительно верхнего края окна.
- bottom - указывает на сколько надо сместить блок относительно нижнего края окна.
Вернемся к нашему примеру. Наши блоки header, menu и footer позиционируются в нормальном потоке, поэтому свойство position для них задавать не надо.
А вот блок content нужно расположить в другом месте, поэтому для него мы укажем свойство position:absolute и зададим смещение: от левого края окна на ширину блока menu, т.е. на 190 пикселов, а от верхнего края окна на высоту блока header, т.е. на 100 пикселов.
Наш блок расположился не совсем так, как ожидалось. Это от того, что мы не учли один нюанс: у браузеров есть свои, встроенные таблицы стилей. И, если мы не задали какое-либо свойство, то используется свойство по умолчанию.
Так, по умолчанию для элемента body определены поля, а мы их не учитывали при задании свойств смещения. Чтобы решить эту проблему, достаточно задать для body свойство margin:0px, т.е. явно указать размер полей (в нашем примере - их отсутствие). Добавим это в таблицу стилей:
body{
margin:0px;
}
Теперь наша страница выглядит так, как мы и ожидали.
В принципе размеры смещения можно было задать и для каждого блока, иногда это необходимо. Главное, что необходимо запомнить: при абсолютном позиционировании следует задать для блока свойство position:absolute и свойства смещения относительно "родительского" элемента. В нашем примере родительским элементом для div-ов было окно браузера, но может быть и по-другому.
Тогда в нашу html-страницу, в div id="content" мы добавим div id="news":
Тогда в таблице стилей смещение мы будем указывать относительно блока content:
Ширина блока content равна 525 пикселов, а ширина блока news - 150 пикселов. Значит, смещение от левого края равно (525-150) 375 пикселов, но, чтобы блок не прилипал к правому краю, мы уменьшили смещение до 365 пикселов.
Аналогично рассчитываем смещение от верхнего края: высота блока content равна 300 пикселов, а высота блока news - 280 пикселов. Значит смещение от верхнего края может быть не более (300-280) 20 пикселов, мы сделали 10.
При абсолютном позиционировании, чтобы не запутаться с величинами смещения, определите сначала "родителя" и помните, что смещение происходит относительно "родителя".
Относительное позиционирование
При относительном позиционировании блока надо задать свойство position:relative и свойства смещения. Смещение в этом случае будет происходить не относительно "родительского" элемента (как при абсолютном позиционировании), а относительно самого блока в нормальном потоке. Это будет понятнее на примере. Пусть у нас есть html-страница с тремя div-ами:
Наш второй блок сместился вниз и вправо относительно того места, где бы он находился в нормальном потоке. Остальные же блоки остались на своих местах. Практически относительное позиционирование применяется достаточно редко, поэтому мы не будем больше уделять этому внимание и рассмотрим плавающие блоки.
Плавающие блоки
Эти блоки нельзя позиционировать с точностью до пиксела, как в предыдущих схемах, но именно эта схема позиционирования очень распространенна. Без плавающих блоков обходится редкий сайт, а уж сделать "резиновую" верстку сайта без них и вовсе невозможно.
Такие блоки могут свободно перемещаться по странице, подобным образом ведут себя картинки в HTML, выровненные с помоьщью параметра align.
Плавающие блоки определяются свойством float, который определяет будет ли блок плавающим и в какую сторону он будет перемещаться. Возможны три варианта:
- left - блок прижимается к левому краю, остальные элементы обтекают его с правой стороны.
- right - блок прижимается к правому краю, остальные элементы обтекают его с левой стороны.
- none - блок не перемещается и позиционируется согласно свойству position.
Давайте посмотрим на примере. Пусть у нас есть html-страница со следующим кодом:
<html>
<head>
<title>Позиционирование блоков</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id="blok1">Текст блока 1</div>
Просто какие-то элементы на странице. Это может быть просто
текст, ссылки, списки, картинки и т.д.
</body>
</html>
И страница style.css со следующим кодом:
#blok1{
border:1px solid red;
width:150px;
height:50px;
}
Сейчас наша страница в браузере выглядит так:
Тогда второй блок прижмется к правому краю первого блока.
Аналогичной будет ситуация при одинаковых значениях right:
Посмотрим на наш блок новостей, видно, что он располагается ниже текста в блоке content. А ведь мы хотели, чтобы блок новостей был справа, а текст обтекал бы его слева.
Почему же у нас так не получилось? Потому что наш блок news в html-коде располагается ниже текста и его будет обтекать только тот текст, который расположен ниже его. Чтобы исправить это надо поместить наш div="news" выше текста (т.е. до слова "контент"):
Вот теперь наш блок новостей находится на своем месте.
А чтобы он не прижимался вплотную к верхнему и правому краям, мы добавим для этого блока значение полей:
Теперь мы добились такого же резельтата, как и при абсолютном позиционировании:
Согласитесь, что с помощью плавающих блоков верстать страницу проще: не надо рассчитывать пикселы, да и код короче. К тому же при "резиновой" верстке мы и не можем указать точное расположение блока на экране, а с помощью плавающих блоков нам это и не нужно, достаточно указать лишь ориентир (слева, справа, ниже или в той же линии).
Фиксированные блоки
Как вы помните при фиксированном позиционировании блок фиксируется относительно области просмотра. В некотором смысле фиксированные блоки похожи на фреймы. Только внутри фрейма доступна прокрутка, а внутри блока нет.
У фиксированных блоков есть один существенный недостаток: они не поддерживаются браузерами Internet Explorer. А потому использовать их пока не следует. Поэтому здесь мы лишь укажем синтаксис такого правила, если хотите попробуйте сами (например, в браузере Opera).
#blok{
position:fixed;
left:0px;
top:0px;
}
Блок с идентификатором "blok" будет при прокрутке страницы оставаться на месте.