Позиционирование блоков. Абсолютное и относительное позиционирование. Плавающие и фиксированные блоки.

31.10.2022 10:59

Позиционирование блоков

    В 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 пикселов.

 
#header{
background:darkred;
width:715px;
height:100px;
}
#menu{
background:oldlace;
width:190px;
height:300px;
}
#content{
background:oldlace;
width:525px;
height:300px;
position:absolute;
left:190px;
top:100px;
}
#footer{
background:darkred;
width:715px;
height:30px;
}
     
Теперь наша страница в браузере выглядит так:
 
 

    Наш блок расположился не совсем так, как ожидалось. Это от того, что мы не учли один нюанс: у браузеров есть свои, встроенные таблицы стилей. И, если мы не задали какое-либо свойство, то используется свойство по умолчанию.

    Так, по умолчанию для элемента body определены поля, а мы их не учитывали при задании свойств смещения. Чтобы решить эту проблему, достаточно задать для body свойство margin:0px, т.е. явно указать размер полей (в нашем примере - их отсутствие). Добавим это в таблицу стилей:

 

body{

margin:0px;

}

     

    Теперь наша страница выглядит так, как мы и ожидали.

    В принципе размеры смещения можно было задать и для каждого блока, иногда это необходимо. Главное, что необходимо запомнить: при абсолютном позиционировании следует задать для блока свойство position:absolute и свойства смещения относительно "родительского" элемента. В нашем примере родительским элементом для div-ов было окно браузера, но может быть и по-другому.

    Предположим, мы решили добавить блок новостей на нашу страницу и разместить его в блоке контента, например, вот так:

    Тогда в нашу html-страницу, в div id="content" мы добавим div id="news":

 
 <html>
 
   <head>
     <title>css potision</title>
     <link rel="stylesheet" type="text/css" href="style.css">
   </head>
 
   <body>
     <div id="header">шапка сайта</div>
     <div id="menu">меню</div>
     <div id="content">
       контент
       <div id="news">блок новостей</div>
     </div>
     <div id="footer">низ сайта</div>
   </body>
 
 </html>
     

    Тогда в таблице стилей смещение мы будем указывать относительно блока content:

 
#news{
background:yellow;
width:150px;
height:280px;
position:absolute;
left:365px;
top:10px;
}
     

    Ширина блока content равна 525 пикселов, а ширина блока news - 150 пикселов. Значит, смещение от левого края равно (525-150) 375 пикселов, но, чтобы блок не прилипал к правому краю, мы уменьшили смещение до 365 пикселов.

    Аналогично рассчитываем смещение от верхнего края: высота блока content равна 300 пикселов, а высота блока news - 280 пикселов. Значит смещение от верхнего края может быть не более (300-280) 20 пикселов, мы сделали 10.

    При абсолютном позиционировании, чтобы не запутаться с величинами смещения, определите сначала "родителя" и помните, что смещение происходит относительно "родителя".

 

Относительное позиционирование

 

    При относительном позиционировании блока надо задать свойство position:relative и свойства смещения. Смещение в этом случае будет происходить не относительно "родительского" элемента (как при абсолютном позиционировании), а относительно самого блока в нормальном потоке. Это будет понятнее на примере. Пусть у нас есть html-страница с тремя div-ами:

 
 <html>
   <head>
     <title>Относительное позиционирование</title>
     <link rel="stylesheet" type="text/css" href="style.css">
   </head>
   <body>
     <div id="blok1">Блок 1</div>
     <div id="blok2">Блок 2</div>
     <div id="blok3">Блок 3</div>
   </body>
 </html>
     
    Давайте зададим в таблице стилей размеры и границы этих блоков:
 
#blok1, #blok2, #blok3 {
border:1px solid red;
width:150px;
height:50px;
}
     

 

    Сейчас наша страница в браузере выглядит так:
    Теперь давайте изменим положение второго блока, для этого добавим в страницу стилей правило:
 
#blok1, #blok2, #blok3 {
border:1px solid red;
width:150px;
height:50px;
}
#blok2{
position:relative;
left:50px;
top:25px;
}
     
    Теперь наша страница выглядит так:

Наш второй блок сместился вниз и вправо относительно того места, где бы он находился в нормальном потоке. Остальные же блоки остались на своих местах. Практически относительное позиционирование применяется достаточно редко, поэтому мы не будем больше уделять этому внимание и рассмотрим плавающие блоки.

 

Плавающие блоки

 

    Эти блоки нельзя позиционировать с точностью до пиксела, как в предыдущих схемах, но именно эта схема позиционирования очень распространенна. Без плавающих блоков обходится редкий сайт, а уж сделать "резиновую" верстку сайта без них и вовсе невозможно.

    Такие блоки могут свободно перемещаться по странице, подобным образом ведут себя картинки в 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;

}

     

Сейчас наша страница в браузере выглядит так:

Давайте сделаем наш блок плавающим и прижмем его к левому краю:
 
#blok1{
border:1px solid red;
width:150px;
height:50px;
float:left;
}
     
Теперь наша страница в браузере выглядит так:

Теперь давайте прижмем блок к правому краю:
 
#blok1{
border:1px solid red;
width:150px;
height:50px;
float:right;
}
     
Теперь наша страница в браузере выглядит так:

А что будет, если плавающих блоков на странице несколько? Давайте добавим в нашу html-страницу еще один блок:
 
 <html>
 
   <head>
     <title>Позиционирование блоков</title>
     <link rel="stylesheet" type="text/css" href="style.css">
   </head>
 
   <body>
     <div id="blok1">Текст блока 1</div>
     <div id="blok2">Текст блока 2</div>
     Просто какие-то элементы на странице. Это может быть просто
     текст, ссылки, списки, картинки и т.д.
   </body>
 
 </html>
     
И зададим им разные значения свойства float:
 
#blok1{
border:1px solid red;
width:150px;
height:50px;
float:left;
}
#blok2{
border:1px solid red;
width:150px;
height:50px;
float:right;
}
     
Теперь наша страница в браузере выглядит так:
 
А если у них будут одинаковые значения? Например:
 
#blok1{
border:1px solid red;
width:150px;
height:50px;
float:left;
}
#blok2{
border:1px solid red;
width:150px;
height:50px;
float:left;
}
     

Тогда второй блок прижмется к правому краю первого блока.

Аналогичной будет ситуация при одинаковых значениях right:

 
#blok1{
border:1px solid red;
width:150px;
height:50px;
float:right;
}
#blok2{
border:1px solid red;
width:150px;
height:50px;
float:right;
}
     
Обратите внимание: сначала к правому краю прижмется блок 1, а уже к нему прижмется блок 2.
 
А что делать, если мы хотим, чтобы блоки были прижаты к правому краю, но располагались бы один под другим. Для этого существует свойство clear, которое определяет, какие стороны плавающего блока не могут соседствовать с другими плавающими блоками. У этог свойства может быть задано одно из четырех значений:
left - блок должен располагаться ниже всех левосторонних блоков.
 
right - блок должен располагаться ниже всех правосторонних блоков.
 
both - блок должен располагаться ниже всех плавающих блоков.
 
none - никаких ограничений нет, это значение по умолчанию.
 
Давайте в нашем последнем примере зададим это свойство для второго блока:
 
#blok1{
border:1px solid red;
width:150px;
height:50px;
float:right;
}
#blok2{
border:1px solid red;
width:150px;
height:50px;
float:right;
clear:right;
}
     
Теперь получилось так, как и хотелось: один блок под другим:
В предыдущей части, мы с вами с помощью абсолютного позиционирования делали вот такую страницу:
Давайте посмотрим, как ее можно сделать с помощью плавающих блоков. Итак, код самой страницы следующий:
 
 <html>
 
   <head>
     <title>Позиционирование блоков</title>
     <link rel="stylesheet" type="text/css" href="style.css">
   </head>
 
   <body>
     <div id="header">шапка сайта</div>
     <div id="menu">меню</div>
     <div id="content">
       контент
       <div id="news">блок новостей</div>
     </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;
}
#news{
background:yellow;
width:150px;
height:280px;
}
     
Сейчас наши блоки располагаются в нормальном потоке, т.е. один под другим. Нам надо сделать блоки menu и content плавающими и левосторонними. А блок news должен прижиматься к правому краю, т.е. его мы сделаем правосторонним плавающим блоком:
 
#header{
background:darkred;
width:715px;
height:100px;
}
#menu{
background:oldlace;
width:190px;
height:300px;
float:left;
}
#content{
background:oldlace;
width:525px;
height:300px;
float:left;
}
#footer{
background:darkred;
width:715px;
height:30px;
}
#news{
background:yellow;
width:150px;
height:280px;
float:right;
}
     
Наша страница в браузере выглядит так:

    Посмотрим на наш блок новостей, видно, что он располагается ниже текста в блоке content. А ведь мы хотели, чтобы блок новостей был справа, а текст обтекал бы его слева.

    Почему же у нас так не получилось? Потому что наш блок news в html-коде располагается ниже текста и его будет обтекать только тот текст, который расположен ниже его. Чтобы исправить это надо поместить наш div="news" выше текста (т.е. до слова "контент"):

 
 <html>
 
   <head>
     <title>Позиционирование блоков</title>
     <link rel="stylesheet" type="text/css" href="style.css">
   </head>
 
   <body>
     <div id="header">шапка сайта</div>
     <div id="menu">меню</div>
     <div id="content">
       <div id="news">блок новостей</div>
       контент
     </div>
     <div id="footer">низ сайта</div>
   </body>
 
 </html>
     

    Вот теперь наш блок новостей находится на своем месте.

    А чтобы он не прижимался вплотную к верхнему и правому краям, мы добавим для этого блока значение полей:

 
#news{
background:yellow;
width:150px;
height:280px;
float:right;
margin:10px;
}
     

    Теперь мы добились такого же резельтата, как и при абсолютном позиционировании:

    Согласитесь, что с помощью плавающих блоков верстать страницу проще: не надо рассчитывать пикселы, да и код короче. К тому же при "резиновой" верстке мы и не можем указать точное расположение блока на экране, а с помощью плавающих блоков нам это и не нужно, достаточно указать лишь ориентир (слева, справа, ниже или в той же линии).

 

Фиксированные блоки

 

    Как вы помните при фиксированном позиционировании блок фиксируется относительно области просмотра. В некотором смысле фиксированные блоки похожи на фреймы. Только внутри фрейма доступна прокрутка, а внутри блока нет.

    У фиксированных блоков есть один существенный недостаток: они не поддерживаются браузерами Internet Explorer. А потому использовать их пока не следует. Поэтому здесь мы лишь укажем синтаксис такого правила, если хотите попробуйте сами (например, в браузере Opera).

 

#blok{

position:fixed;

left:0px;

top:0px;

}

     

    Блок с идентификатором "blok" будет при прокрутке страницы оставаться на месте.