position определяет, как браузер размещает элемент на странице: static - в обычном потоке без изменений, а остальные четыре значения (relative, absolute, fixed, sticky) позволяют сдвигать элемент через top, right, bottom и left - каждое по-своему обращается с местом элемента в потоке документа.
В этом уроке
Попробуй прямо сейчас: убери у .parent строку position: relative - блок .abs-box "выпрыгнет" и спозиционируется уже не относительно родителя, а относительно всей страницы.
position: static - точка отсчёта по умолчанию
static - это значение position у любого элемента, если явно не задать другое. Элемент стоит в обычном потоке документа, как будто position вообще не существует - свойства top, right, bottom, left и z-index у static-элемента полностью игнорируются браузером, сколько бы их ни задавать.
position: static; - или вообще не указывать position - для большинства элементов на странице это ожидаемое, "невидимое" поведение.
position: static; top: 50px;, ожидая, что элемент сдвинется вниз на 50px - top у static-элемента не работает вообще; чтобы сдвиг сработал, нужно сначала сменить position на relative или другое непустое значение.
Четыре способа сдвинуть элемент: relative, absolute, fixed, sticky
relative сдвигает элемент от его обычного места, но место в потоке документа за ним сохраняется - как будто там остался невидимый "след" на прежнем месте, и соседние элементы ведут себя так, будто элемент не двигался. absolute, наоборот, полностью убирает элемент из потока - место под ним не резервируется, а сам элемент позиционируется относительно ближайшего предка с любым position, кроме static (если такого предка нет - относительно всей страницы). fixed похож на absolute, но точка отсчёта - не предок, а окно просмотра целиком, поэтому элемент остаётся на экране при прокрутке. sticky - гибрид: ведёт себя как relative, пока страница не прокрутится до заданного порога (top, bottom и так далее), а затем "прилипает" как fixed внутри своего прокручиваемого родителя.
position: relative; top: 10px; - элемент сдвинется на 10px вниз, а место, которое он занимал, останется зарезервированным для расчёта разметки.
position: absolute; без position: relative у родителя, ожидая позиционирование "внутри" этого блока - без позиционированного предка absolute отсчитывается от всей страницы, а не от ближайшего визуально блока.
top/right/bottom/left и z-index: как ими пользоваться
top, right, bottom и left задают расстояние от соответствующего края - но только у relative, absolute, fixed и sticky; у static они ничего не делают. Похожая история с z-index: он определяет, какой из перекрывающихся элементов окажется сверху, но применяется ТОЛЬКО к позиционированным элементам - у static-элемента z-index игнорируется полностью, даже если задать z-index: 9999.
position: relative; z-index: 2; - z-index сработает, элемент позиционирован.
z-index: 999; у элемента без position (то есть со значением по умолчанию static), ожидая, что он окажется поверх всего - z-index у static-элемента не действует, порядок наложения определится обычным порядком в HTML-коде, как будто z-index не задавали вовсе.
Частые ошибки новичков
| Ошибка | Что происходит | Как исправить |
|---|---|---|
| Задают top/left элементу с position: static (или без position вовсе) | Свойства полностью игнорируются, элемент остаётся на обычном месте | Сначала сменить position на relative, absolute, fixed или sticky |
| Ставят absolute-элемент без position: relative у родителя | Элемент позиционируется относительно всей страницы, а не ожидаемого блока | Задать ближайшему нужному предку любой position, кроме static (обычно relative) |
| Задают z-index элементу с position: static | z-index полностью игнорируется, порядок наложения определяется просто порядком в коде | Задать элементу непустой position (relative и так далее) - тогда z-index заработает |
| Путают relative и absolute по поведению с местом в потоке | Ожидают, что relative освобождает место, как absolute (или наоборот) | Помнить: relative резервирует прежнее место, absolute - нет |
Шпаргалка
| Что нужно | Значение position |
|---|---|
| Обычный поток, ничего не менять | static (по умолчанию) |
| Сдвинуть элемент, оставив место под ним | relative |
| Позиционировать внутри конкретного блока, без резерва места | absolute (у родителя - relative) |
| Закрепить элемент на экране при прокрутке | fixed |
| "Прилипнуть" после прокрутки до порога | sticky |
| Чтобы z-index сработал | любой position, кроме static |
Коротко: отвечаем на вопросы
Чем отличаются position: relative и position: absolute?
relative сдвигает элемент от его обычного места, но резервирует это место для остальной разметки - соседние элементы не двигаются. absolute полностью убирает элемент из потока (место не резервируется) и позиционирует его относительно ближайшего предка с непустым position, а не от своего исходного места.
Почему z-index не работает у моего элемента?
Скорее всего, у элемента position: static (значение по умолчанию, если position вообще не задан) - z-index применяется только к элементам с непустым position: relative, absolute, fixed или sticky. Достаточно задать один из этих вариантов, чтобы z-index заработал.
Нужно ли всегда указывать top/left, если элемент позиционирован?
Для relative, absolute и fixed - нет, без top/left/right/bottom элемент просто останется на своём обычном месте (для static-подобных случаев) или в начале координат предка. А вот sticky требует хотя бы одного из этих свойств, иначе он ведёт себя как обычный relative и никогда не "прилипает".