Позиционирование и слои

static, relative, absolute, fixed, sticky: как вынуть элемент из потока, прилепить к родителю и управлять z-index без хаоса.

Уровень: средний 11 разделов 1,5 часа

1. static и поток

По умолчанию элементы в static: лежат в потоке, не слушают свойства top/left/right/bottom/z-index. Позиционирование начинается с двух китов: relative — «уехать» от своего места, absolute — от ближайшего позиционированного предка.

2. relative

.badge {
  position: relative;   /* сам остаётся в потоке */
  top: 8px;             /* смещается на 8px вниз от своего места */
  left: -4px;
}

/* relative + z-index превращает элемент в «предка для absolute» */

3. absolute

absolute вынимает элемент из потока и позиционирует его относительно ближайшего позиционированного предка (relative/absolute/fixed/sticky), а если такого нет — относительно страницы.

.card { position: relative; }
.card__badge {
  position: absolute;
  top: 12px; right: 12px;
  background: #ef4444;
  color: #fff;
}
Классика: absolute для «плавающих» бейджей, иконок-наложений, стрелок и тултипов. Всегда задавайте предку position: relative.

4. fixed и sticky

.menu { position: fixed; top: 0; left: 0; right: 0; }
/* липнет к окну — не работает внутри transform-предка (создает контекст) */

.sidebar { position: sticky; top: 24px; }
/* прилипает к предку-контейнеру, пока тот не кончился */

5. offset-свойства и центрирование

.loader {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
}

/* или через inset + margin: auto */
.wrap { position: absolute; inset: 0; }
.wrap .child { margin: auto; }
absolute + top/left 50% + translate — «честное» центрирование по обоим осям. inset: 0 расширяет до предка — идеально для оверлеев и наложений.

6. z-index и наложение

z-index работает только на позиционированных элементах (и флекс/грид-детях). Он решает, кто сверху при пересечении. Большие числа — плохо: проще управлять уровнями 1, 2, 10 + переменная.

.menu { position: sticky; z-index: 10; }
.popup { position: fixed; z-index: 100; }

:root {
  --z-dropdown: 10;
  --z-popup: 100;
}

7. Контекст наложения

Контекст наложения — «мир» внутри элемента: его дети сортируются между собой, не мешая остальной странице. Контекст создают position+z-index, transform, filter, opacity<1, will-change.

.popup { transform: scale(0.9); }  /* transform создаёт контекст —
                                        popup визуально «выше» не поднимет */
transform/filter на родителе «запирают» позиционированного ребёнка: он не выйдет за пределы контекста и не поднимется над внешними слоями.

8. Всплывание fixed внутри transform

.dialog { position: fixed; }      /* задумано к вьюпорту */
.main { transform: translateX(0); }  /* но предок с transform
                                        становится его контейнером */

Если модалка вдруг «прилипла» к блоку, а не к окну — почти всегда предок с transform или filter. Решение: выносить модалку в или убрать transform с предка.

9. Стек: как построить карточку с наложением

.card { position: relative; }
.card__image { position: absolute; inset: 0; }
.card__text { position: relative; z-index: 1; }

/* после напишите z-index февраль в переменных — и слои чисты */

10. Ошибки позиционирования

ОшибкаСимптом
absolute без relative-предкаулетает на страницу
z-index без positionне работает
sticky в overflow:hiddenне липнет
fixed в transformпривязан к блоку, не к окну
top:50% без translateсмещённо на половину своей высоты

Три из пяти лечатся тремя вещами: не забыть relative у предка, не прятать sticky в overflow и помнить про translate для центровки.

11. Чек-лист позиционирования

Что дальше

Курс завершён.

← Вернуться к курсам