# Свойство "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` - сдвиг справа
Не будут работать одновременно указанные `top` и `bottom`, `left` и `right`. Нужно использовать только одну границу из каждой пары.
**Возможны отрицательные координаты** и координаты, использующие другие единицы измерения. Например, `left: 10%` сдвинет элемент на 10% его ширины вправо, а `left: -10%` -- влево. При этом часть элемента может оказаться за границей окна:
```html
*!*
*/!*
Заголовок сдвинут на 10% влево.
Заголовок
А тут - всякий разный текст...
... В две строки!
```
**Свойства `left/top` не будут работать для `position:static`**. Если их все же поставить, браузер их проигнорирует. Эти свойства предназначены для работы только с позиционированными элементами.
## position: absolute
Синтаксис:
```css
position: absolute;
```
Абсолютное позиционирование делает две вещи:
**Элемент исчезает с того места, где он должен быть и позиционируется заново.** Остальные элементы, располагаются так, как будто этого элемента никогда не было.
**Координаты `top/bottom/left/right` для нового местоположения отсчитываются от ближайшего позиционированного родителя**, т.е. родителя с позиционированием, отличным от `static`. Если такого родителя нет -- то относительно документа.
Кроме того:
**Ширина элемента с `position: absolute` устанавливается по содержимому.** Детали алгоритма вычисления ширины [описаны в стандарте](http://www.w3.org/TR/CSS2/visudet.html#abs-non-replaced-width).
**Элемент получает `display:block`**, который перекрывает почти все возможные `display` (см. [Relationships between 'display', 'position', and 'float'](http://www.w3.org/TR/CSS2/visuren.html#dis-pos-flo)).
Например, отпозиционируем заголовок в правом-верхнем углу документа:
```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`
Сдвигает элемент относительно текущего места.
Противоположные границы `left/right` (`top/bottom`) одновременно указать нельзя.
Окружающие элементы ведут себя так, как будто элемент не сдвигался.
`absolute`
Визуально переносит элемент на новое место.
Новое место вычисляется по координатам `left/top/right/bottom` относительно ближайшего позиционированного родителя. Если такого родителя нет, то им считается окно.
Ширина элемента по умолчанию устанавливается по содержимому.
Можно указать противположные границы `left/right` (`top/bottom`). Элемент растянется. Возможность не поддерживается в IE7-.
Окружающие элементы заполняют освободившееся место.
`fixed`
Подвид абсолютного позиционирования, при котором элемент привязывается к координатам окна, а не документа.
При прокрутке он остаётся на том же месте.