# Свойство "position" Свойство `position` позволяет сдвигать элемент со своего обычного места. Цель этой главы -- не только напомнить, как оно работает, но и разобрать ряд частых заблуждений и граблей. [cut] ## position: static *Статическое позиционирование* производится по умолчанию, в том случае, если свойство `position` не указано. Его можно также явно указать через CSS-свойство: ```css position: static; ``` Такая запись встречается редко и используется для переопределения других значений `position`. Здесь и далее, для примеров мы будем использовать следующий документ: ```html
Без позиционирования ("position: static").

Заголовок

А тут - всякий разный текст...
... В две строки!
``` В этом документе сейчас все элементы отпозиционированы статически, то есть никак. [summary] Элемент с `position: static` еще называют *не позиционированым*. [/summary] ## position: relative *Относительное позиционирование* сдвигает элемент относительно его обычного положения. Для того, чтобы применить относительное позиционирование, необходимо указать элементу CSS-свойство `position: relative` и координаты `left/right/top/bottom`. Этот стиль сдвинет элемент на 10 пикселей относительно обычной позиции по вертикали: ```css position: relative; top: 10px; ``` ```html *!* */!*
Заголовок сдвинут на 10px вниз.

Заголовок

А тут - всякий разный текст...
... В две строки!
``` ### Координаты Для сдвига можно использовать координаты: Не будут работать одновременно указанные `top` и `bottom`, `left` и `right`. Нужно использовать только одну границу из каждой пары. **Возможны отрицательные координаты** и координаты, использующие другие единицы измерения. Например, `left: 10%` сдвинет элемент на 10% его ширины вправо, а `left: -10%` -- влево. При этом часть элемента может оказаться за границей окна: ```html *!* */!*
Заголовок сдвинут на 10% влево.

Заголовок

А тут - всякий разный текст...
... В две строки!
``` **Свойства `left/top` не будут работать для `position:static`**. Если их все же поставить, браузер их проигнорирует. Эти свойства предназначены для работы только с позиционированными элементами. ## position: absolute Синтаксис: ```css position: absolute; ``` Абсолютное позиционирование делает две вещи:
  1. **Элемент исчезает с того места, где он должен быть и позиционируется заново.** Остальные элементы, располагаются так, как будто этого элемента никогда не было.
  2. **Координаты `top/bottom/left/right` для нового местоположения отсчитываются от ближайшего позиционированного родителя**, т.е. родителя с позиционированием, отличным от `static`. Если такого родителя нет -- то относительно документа.
Кроме того: Например, отпозиционируем заголовок в правом-верхнем углу документа: ```html *!* */!*
Заголовок в правом-верхнем углу документа.

Заголовок

А тут - всякий разный текст...
... В две строки!
``` Важное отличие от `relative`: **так как элемент удаляется со своего обычного места, то элементы под ним сдвигаются, занимая освободившееся пространство**. Это видно в примере выше: строки идут одна за другой. Так как при `position:absolute` размер блока устанавливается по содержимому, то широкий `Заголовок` "съёжился" до прямоугольника в углу. Иногда бывает нужно поменять элементу `position` на `absolute`, но так, чтобы элементы вокруг не сдвигались. Как правило это делают, меняя соседей -- добавляют `margin/padding` или вставляют в документ пустой элемент с такими же размерами. [smart header="Одновременное указание `left/right`, `top/bottom`"] **В абсолютно позиционированном элементе можно одновременно задавать противоположные границы.** Браузер растянет такой элемент до границ. Работает везде, кроме IE6: ```html
10px от границ
``` [/smart] [smart header="Внешним блоком является окно"] Как растянуть абсолютно позиционированный блок на всю ширину документа? Первое, что может прийти в голову: ```css div { position: absolute; left: 0; top: 0; /* в левый-верхний угол */ width: 100%; height: 100%; /* .. и растянуть */ } ``` Но это будет работать лишь до тех пор, пока у страницы не появится скроллинг! Прокрутите вниз ифрейм: [iframe src="position-100-wrong" height=200 link] **Вы увидите, что голубой фон оканчивается задолго до конца документа.** Дело в том, что в CSS `100%` относится к ширине внешнего блока ("containing block"). А какой внешний блок имеется в виду здесь, ведь элемент изъят со своего обычного места? В данном случае им является так называемый (["\"initial containing block\""](http://www.w3.org/TR/CSS21/visudet.html#containing-block-details)), которым является окно, *а не документ*. **То есть, координаты и ширины вычисляются относительно окна, а не документа.** Может быть, получится так? ```css div { position: absolute; left: 0; top: 0; /* в левый-верхний угол, и растянуть.. */ right: 0; bottom: 0; /* ..указанием противоположных границ */ } ``` С виду логично, но нет, не получится! Координаты `top/right/left/bottom` вычисляются относительно *окна*. Значение `bottom: 0` -- нижняя граница окна, а не документа, блок растянется до неё. То есть, будет то же самое, что и в предыдущем примере. [/smart] ## position: absolute в позиционированном родителе Если у элемента есть позиционированный предок, то `position: absolute` работает относительно него, а не относительно документа. То есть, достаточно поставить родительскому `div` позицию `relative`, даже без координат -- и заголовок будет в его правом-верхнем углу, вот так: ```html *!* */!*
Заголовок в правом-верхнем углу DIV'а.

Заголовок

А тут - всякий разный текст...
... В две строки!
``` Нужно пользоваться таким позиционированием с осторожностью, т.к оно может перекрыть текст. Этим оно отличается от `float`. Сравните: ## position: fixed Это подвид абсолютного позиционирования. Синтаксис: ```css position: fixed; ``` Позиционирует объект точно так же, как `absolute`, но относительно `window`. Разница в нескольких словах: **Когда страницу прокручивают, фиксированный элемент остается на своем месте и не прокручивается вместе со страницей.** В следующем примере, при прокрутке документа, ссылка `#top` всегда остается на своем месте. ```html *!*Наверх (остается при прокрутке)*/!* Фиксированное позиционирование.

Текст страницы.. Прокрути меня...

Много строк..

Много строк..

Много строк..

Много строк..

Много строк..

Много строк..

Много строк..

Много строк..

``` Поддерживается во всех современных браузерах, в IE начиная с версии 7. Для реализации аналогичного функционала в IE6 используют CSS-выражения. ## Итого Виды позиционирования и их особенности.
`static`
Иначе называется "без позиционирования". В явном виде задаётся только если надо переопределить другое правило CSS.
`relative`
Сдвигает элемент относительно текущего места.
`absolute`
Визуально переносит элемент на новое место. Новое место вычисляется по координатам `left/top/right/bottom` относительно ближайшего позиционированного родителя. Если такого родителя нет, то им считается окно.
`fixed`
Подвид абсолютного позиционирования, при котором элемент привязывается к координатам окна, а не документа. При прокрутке он остаётся на том же месте.
## Почитать CSS-позиционирование по-настоящему глубоко в спецификации Visual Formatting Model, 9.3 и ниже. Еще есть хорошее руководство CSS Positioning in 10 steps, которое охватывает основные типы позиционирования.