Зачем нужно CSS-свойство position и как оно работает
Управляем поведением элементов веб-страницы.
Представьте: вы листаете ленту соцсетей и хотите перейти в другой раздел, но боковое меню уже скрылось за верхним краем экрана и приходится прокручивать страницу обратно. Чтобы меню оставалось под рукой, нужно настроить его положение и поведение при прокрутке. С этим поможет CSS-свойство position.
В этой статье мы разберём значения свойства position, объясним, как они связаны с потоком документа и откуда браузер отсчитывает положение элемента. На примерах покажем, как закреплять блоки при прокрутке, размещать их относительно контейнера и управлять порядком наложения.
Содержание
- Что такое свойство position
- Как использовать position
- Значения свойства position
- Советы по использованию
Что такое свойство position
CSS-свойство position задаёт способ позиционирования элемента относительно других объектов на странице и в области просмотра браузера. Благодаря этому разработчики могут создавать сложные структуры страниц.
Свойство position стоит применять, когда элементы невозможно или нецелесообразно позиционировать с помощью Flexbox и Grid. Например, чтобы наложить иконку Play на видеопревью или создать кнопку «Наверх», зафиксированную в углу экрана.
Другой пример использования position — всплывающая подсказка, которая появляется над текстом при наведении мыши. Ей можно задать position: absolute, а её родительскому контейнеру — position: relative. Тогда подсказка будет располагаться относительно этого контейнера и не будет сдвигать соседние элементы.
Как использовать position
В качестве примера создадим в HTML-код базовый контейнер с четырьмя блоками:
<div class="container">
<div class="box box-1">Блок 1</div>
<div class="box box-2">Блок 2</div>
<div class="box box-3">Блок 3</div>
<div class="box box-4">Блок 4</div>
</div>
<div style="height: 150vh;"></div>К контейнеру подключим базовые CSS-стили:
body {
font-family: sans-serif;
margin: 20px;
}
.container {
padding: 15px;
border: 3px dashed #ccc;
}
.box {
width: 120px;
height: 120px;
margin-bottom: 15px;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.2em;
font-weight: bold;
color: white;
border-radius: 8px;
}
.box-1 { background-color: #4A90E2; }
.box-2 { background-color: #50E3C2; }
.box-3 { background-color: #F5A623; }
.box-4 { background-color: #D0021B; }Если посмотреть на нашу страницу в браузере, то все четыре блока будут стоять в ряд друг под другом, хотя мы явно не указывали их позиционирование относительно друг друга. В классах box-1, box-2, box-3 и box-4 мы обозначили только цвет блоков.

Всё потому что элементы получают значение свойства position по умолчанию — static. Само по себе значение static не выстраивает элементы сверху вниз. Их расположение зависит от правил раскладки: обычные блоки идут друг под другом, строчные элементы — в строку, а элементы внутри Flexbox и Grid — по правилам контейнера.
В нашем примере четыре блока располагаются друг под другом. Если явно задать первому блоку position: static, ничего не изменится.
.box-1 {
position: static;
}Значения свойства position
У position пять основных значений. Со static мы уже знакомы — разберём relative, absolute, fixed и sticky.
Положение элемента задают с помощью top, right, bottom и left. Их можно объединить в сокращённую запись inset: например, inset: 10px 20px задаёт top и bottom по 10px, а left и right — по 20px.
Эти свойства работают по-разному в зависимости от значения position. На результат также влияют стили предков и размеры области просмотра браузера. Посмотрим в каждом примере, откуда браузер отсчитывает положение элемента и что происходит с местом элемента в потоке.
relative — сдвиг относительно исходного места
Значение relative сдвигает элемент относительно того места, которое он занимал бы при static. Например, top: 30px сдвинет его вниз на 30 пикселей, а left: 50px — вправо на 50 пикселей.
Элемент остаётся в потоке: браузер сохраняет под него прежнее место. Соседние элементы располагаются так, будто сдвига не было, поэтому элемент может их перекрыть. Например, так можно немного сдвинуть иконку в меню, не сдвигая остальные пункты.
Точка отсчёта такого смещения — исходное положение самого элемента, а не край родителя.
.box-2 {
position: relative;
top: 30px;
left: 50px;
}Второй блок переместится вниз и вправо, а первый, третий и четвёртый останутся на своих местах.

Изображение: Skillbox Media
absolute — элемент вне потока
Значение absolute исключает элемент из обычного потока. Место под него не сохраняется: соседи располагаются так, будто его нет. Это удобно, например, чтобы разместить кнопку закрытия в углу модального окна поверх его содержимого.
Обычно положение такого элемента отсчитывается от ближайшего предка с position, отличным от static: relative, absolute, fixed или sticky. Это может быть непосредственный родитель или контейнер на несколько уровней выше.
Чтобы задать точку отсчёта явно, контейнеру обычно указывают position: relative.
.container {
position: relative;
height: 400px;
}
.box-3 {
position: absolute;
top: 20px;
right: 20px;
}Третий блок расположится на расстоянии 20 пикселей от верхнего и правого внутренних краёв рамки .container. Четвёртый блок поднимется и займёт его прежнее место в потоке.

fixed — закрепление при прокрутке
Значение fixed исключает элемент из потока и обычно закрепляет его относительно области просмотра браузера. При прокрутке страницы элемент сохраняет своё положение в окне.
Так можно закрепить навигационную панель, кнопку «Наверх» или корзину магазина. Место под элемент не сохраняется, поэтому он может перекрывать содержимое страницы.
В нашем примере закрепим четвёртый блок в правом нижнем углу:
.box-4 {
position: fixed;
bottom: 30px;
right: 30px;
margin: 0;
}Блок расположится в 30 пикселях от нижнего и правого краёв области просмотра. Значение margin: 0 убирает внешний отступ из базовых стилей, чтобы он не увеличивал это расстояние. Прокрутите страницу — блок останется на месте.


sticky — прилипание при прокрутке
Значение sticky удерживает элемент у заданного края при прокрутке, пока это позволяют границы его контейнера. Его используют, например, для заголовков разделов и шапок длинных таблиц.
Элемент остаётся в потоке всё время — и до прилипания, и после. Браузер сохраняет под него место, поэтому соседние элементы не сдвигаются в момент прилипания.
Для прилипания по вертикали нужно задать top или bottom. В нашем примере используем top: 0.
.box-1 {
position: sticky;
top: 0;
}При прокрутке первый блок сначала движется вместе со страницей. Когда его верхний край достигает верхнего края области просмотра, блок прилипает. Он остаётся там, пока нижняя граница .container не начнёт выталкивать его вверх.


Советы по использованию
Ниже мы собрали несколько лайфхаков и советов по использованию position в вёрстке.
Задавайте точку отсчёта для absolute-элементов
Если элемент должен располагаться относительно конкретного контейнера, задайте этому контейнеру position: relative. Так, например, можно разместить кнопку в углу карточки.
.container {
position: relative; /* Контекст позиционирования */
height: 400px;
border: 3px solid #000;
}
.box-3 {
position: absolute;
/* Теперь блок позиционируется не от окна, а от контейнера */
bottom: 10px;
right: 10px;
}Третий блок расположится в правом нижнем углу контейнера. margin: 0 убирает внешний отступ из базовых стилей, чтобы расстояние до края составляло ровно 10 пикселей.
Явно задавать контейнеру ширину и высоту необязательно: его размеры могут зависеть от содержимого. Но если внутри только absolute-элементы, то они не растянут его по высоте. Тогда размер нужно задать отдельно — например, через height, как в этом примере.
Настраивайте sticky для нужной области прокрутки
Если элемент должен прилипать внутри отдельного прокручиваемого контейнера, ограничьте высоту контейнера и добавьте overflow: auto. Прокрутка появится, когда содержимое перестанет помещаться по высоте.
.container {
height: 300px;
overflow: auto;
border: 3px solid #000;
}
.box-2 {
position: sticky;
top: 0;
}Прокручивайте сам контейнер: второй блок поднимется до верхнего края его области прокрутки и прилипнет.
Высота контейнера не обязана превышать высоту окна браузера. Важно, чтобы содержимому хватало прокрутки для достижения точки прилипания, а самому элементу — места для смещения.
Если элемент должен прилипать при прокрутке всей страницы, добавлять overflow: auto родителю не нужно. Проверьте также, не создаёт ли кто-то из предков отдельный контейнер прокрутки: он может изменить область прилипания.
Управляйте порядком наложения через z-index
Свойство z-index задаёт порядок перекрывающихся элементов. В пределах одного контекста наложения элементы с большим значением располагаются выше элементов с меньшим.
.container {
position: relative;
height: 250px;
}
.box {
position: absolute;
}
.box-1 {
top: 20px;
left: 20px;
z-index: 1;
}
.box-2 {
top: 60px;
left: 60px;
z-index: 2;
}
.box-3 {
top: 100px;
left: 40px;
z-index: 0;
}
.box-4 {
display: none;
}В этом примере второй блок перекроет первый и третий, а первый — третий. Для такого порядка достаточно значений 0, 1 и 2.
Без z-index браузер тоже располагает элементы по правилам CSS, а не случайным образом. Например, если убрать z-index из этого примера, при перекрытии выше окажется блок, который идёт позже в HTML.
Свойство работает у элементов с position, отличным от static, а также у flex и grid-элементов.
Большое значение вроде 9999 не гарантирует, что элемент окажется поверх всей страницы. Если он вложен в отдельный контекст наложения, его положение зависит и от порядка этого контекста среди соседних.
Больше интересного про код — в нашем телеграм-канале. Подписывайтесь!