16 KiB
Свойство "position"
Свойство position
позволяет сдвигать элемент со своего обычного места. Цель этой главы -- не только напомнить, как оно работает, но и разобрать ряд частых заблуждений и граблей.
[cut]
position: static
Статическое позиционирование производится по умолчанию, в том случае, если свойство position
не указано.
Его можно также явно указать через CSS-свойство:
position: static;
Такая запись встречается редко и используется для переопределения других значений position
.
Здесь и далее, для примеров мы будем использовать следующий документ:
<!--+ autorun height=200 -->
<div style="background: #aef; width: 500px">
Без позиционирования ("position: static").
<h2 style="background: #fee; margin: 0">Заголовок</h2>
<div>А тут - всякий разный текст... <br/>
... В две строки!</div>
</div>
В этом документе сейчас все элементы отпозиционированы статически, то есть никак.
[summary]
Элемент с position: static
еще называют не позиционированым.
[/summary]
position: relative
Относительное позиционирование сдвигает элемент относительно его обычного положения.
Для того, чтобы применить относительное позиционирование, необходимо указать элементу CSS-свойство position: relative
и координаты left/right/top/bottom
.
Этот стиль сдвинет элемент на 10 пикселей относительно обычной позиции по вертикали:
position: relative;
top: 10px;
<!--+ autorun height=200 -->
*!*
<style>
h2 {
position: relative;
top: 10px;
}
</style>
*/!*
<div style="background: #aef; width: 500px">
Заголовок сдвинут на 10px вниз.
<h2 style="background: #fee; margin: 0;">Заголовок</h2>
<div>А тут - всякий разный текст... <br/>
... В две строки!</div>
</div>
Координаты
Для сдвига можно использовать координаты:
- `top` - сдвиг от "обычной" верхней границы
- `bottom` - сдвиг от нижней границы
- `left` - сдвиг слева
- `right` - сдвиг справа
Не будут работать одновременно указанные top
и bottom
, left
и right
. Нужно использовать только одну границу из каждой пары.
Возможны отрицательные координаты и координаты, использующие другие единицы измерения. Например, left: 10%
сдвинет элемент на 10% его ширины вправо, а left: -10%
-- влево. При этом часть элемента может оказаться за границей окна:
<!--+ autorun height=200 -->
*!*
<style>
h2 {
position: relative;
left: -10%;
}
</style>
*/!*
<div style="background: #aef; width: 500px">
Заголовок сдвинут на 10% влево.
<h2 style="background: #fee; margin: 0;">Заголовок</h2>
<div>А тут - всякий разный текст... <br/>
... В две строки!</div>
</div>
Свойства left/top
не будут работать для position:static
. Если их все же поставить, браузер их проигнорирует. Эти свойства предназначены для работы только с позиционированными элементами.
position: absolute
Синтаксис:
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)).
Например, отпозиционируем заголовок в правом-верхнем углу документа:
<!--+ autorun height=200 -->
*!*
<style>
h2 {
position: absolute;
right: 0;
top: 0;
}
</style>
*/!*
<div style="background: #aef; width: 500px">
Заголовок в правом-верхнем углу документа.
<h2 style="background: #fee; margin: 0;">Заголовок</h2>
<div>А тут - всякий разный текст... <br/>
... В две строки!</div>
</div>
Важное отличие от relative
: так как элемент удаляется со своего обычного места, то элементы под ним сдвигаются, занимая освободившееся пространство. Это видно в примере выше: строки идут одна за другой.
Так как при position:absolute
размер блока устанавливается по содержимому, то
широкий Заголовок
"съёжился" до прямоугольника в углу.
Иногда бывает нужно поменять элементу position
на absolute
, но так, чтобы элементы вокруг не сдвигались. Как правило это делают, меняя соседей -- добавляют margin/padding
или вставляют в документ пустой элемент с такими же размерами.
[smart header="Одновременное указание left/right
, top/bottom
"]
В абсолютно позиционированном элементе можно одновременно задавать противоположные границы.
Браузер растянет такой элемент до границ. Работает везде, кроме IE6:
<!--+ autorun height=50 -->
<style>
*!*
div {
position: absolute;
left: 10px; right: 10px; top: 10px; bottom: 10px;
}
*/!*
</style>
<div style="background:#aef;text-align:center">10px от границ</div>
[/smart]
[smart header="Внешним блоком является окно"] Как растянуть абсолютно позиционированный блок на всю ширину документа?
Первое, что может прийти в голову:
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""), которым является окно, а не документ.
То есть, координаты и ширины вычисляются относительно окна, а не документа.
Может быть, получится так?
div {
position: absolute;
left: 0; top: 0; /* в левый-верхний угол, и растянуть.. */
right: 0; bottom: 0; /* ..указанием противоположных границ */
}
С виду логично, но нет, не получится!
Координаты top/right/left/bottom
вычисляются относительно окна. Значение bottom: 0
-- нижняя граница окна, а не документа, блок растянется до неё. То есть, будет то же самое, что и в предыдущем примере.
[/smart]
position: absolute в позиционированном родителе
Если у элемента есть позиционированный предок, то position: absolute
работает относительно него, а не относительно документа.
То есть, достаточно поставить родительскому div
позицию relative
, даже без координат -- и заголовок будет в его правом-верхнем углу, вот так:
<!--+ autorun height=200 -->
*!*
<style>
h2 {
position: absolute;
right: 0;
top: 0;
}
</style>
*/!*
<div style="background: #aef; width: 500px; *!*position: relative*/!*">
Заголовок в правом-верхнем углу DIV'а.
<h2 style="background: #fee; margin: 0;">Заголовок</h2>
<div>А тут - всякий разный текст... <br/>
... В две строки!</div>
</div>
Нужно пользоваться таким позиционированием с осторожностью, т.к оно может перекрыть текст. Этим оно отличается от float
.
Сравните:
- Используем `position` для размещения элемента управления:
<!--+ autorun height=80 --> <button style="position: absolute; right: 10px; opacity: 0.8"> Кнопка </button> 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9
Часть текста перекрывается. Кнопка более не участвует в потоке.
- Используем `float` для размещения элемента управления:
<!--+ autorun height=80 --> <button style="float: right; margin-right: 10px; opacity: 0.8;"> Кнопка </button> 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9
Браузер освобождает место справа, текст перенесён. Кнопка продолжает находиться в потоке, просто сдвинута.
position: fixed
Это подвид абсолютного позиционирования.
Синтаксис:
position: fixed;
Позиционирует объект точно так же, как absolute
, но относительно window
.
Разница в нескольких словах:
Когда страницу прокручивают, фиксированный элемент остается на своем месте и не прокручивается вместе со страницей.
В следующем примере, при прокрутке документа, ссылка #top
всегда остается на своем месте.
<!--+ autorun untrusted height=200 -->
<style>
*!*
#top {
position: fixed;
right: 10px;
top: 10px;
background: #fee;
}
*/!*
</style>
*!*<a href="#" id="top">Наверх (остается при прокрутке)</a>*/!*
Фиксированное позиционирование.
<p>Текст страницы.. Прокрути меня...</p>
<p>Много строк..</p><p>Много строк..</p>
<p>Много строк..</p><p>Много строк..</p>
<p>Много строк..</p><p>Много строк..</p>
<p>Много строк..</p><p>Много строк..</p>
Поддерживается во всех современных браузерах, в IE начиная с версии 7. Для реализации аналогичного функционала в IE6 используют CSS-выражения.
Итого
Виды позиционирования и их особенности.
- `static`
- Иначе называется "без позиционирования". В явном виде задаётся только если надо переопределить другое правило CSS.
- `relative`
- Сдвигает элемент относительно текущего места.
- Противоположные границы `left/right` (`top/bottom`) одновременно указать нельзя.
- Окружающие элементы ведут себя так, как будто элемент не сдвигался.
- `absolute`
- Визуально переносит элемент на новое место.
Новое место вычисляется по координатам
left/top/right/bottom
относительно ближайшего позиционированного родителя. Если такого родителя нет, то им считается окно.- Ширина элемента по умолчанию устанавливается по содержимому.
- Можно указать противположные границы `left/right` (`top/bottom`). Элемент растянется. Возможность не поддерживается в IE7-.
- Окружающие элементы заполняют освободившееся место.
- `fixed`
- Подвид абсолютного позиционирования, при котором элемент привязывается к координатам окна, а не документа.
При прокрутке он остаётся на том же месте.
Почитать
CSS-позиционирование по-настоящему глубоко в спецификации Visual Formatting Model, 9.3 и ниже.
Еще есть хорошее руководство CSS Positioning in 10 steps, которое охватывает основные типы позиционирования.