HTML/CSSMiddleTechnical

В чём разница между position: relative, absolute, fixed, sticky и static?

static — в потоке без смещений; relative — в потоке, смещается визуально и создаёт containing block; absolute — вне потока, relative to ближайшего positioned предка; fixed — relative to viewport; sticky — прилипает при прокрутке в рамках scroll container.

Пять значений position

Свойство position определяет, как элемент участвует в потоке документа и относительно чего вычисляются его смещения (top, right, bottom, left).

static (по умолчанию)

Элемент находится в обычном потоке. Свойства смещения (top, left, …) не применяются. z-index не работает. Это поведение по умолчанию для всех элементов.

relative

Элемент остаётся в потоке (занимает своё место), но визуально смещается относительно этого места. Важно: смещение не влияет на соседей — они не перестраиваются. Также relative создаёт containing block для дочерних absolute-элементов.

.tooltip-anchor {
  position: relative; /* создаём containing block */
}

.tooltip {
  position: absolute;
  top: 100%;  /* отступ от нижней границы .tooltip-anchor */
  left: 0;
}

absolute

Элемент вырывается из потока — не занимает место в лейауте. Позиционируется относительно ближайшего предка с position, отличным от static (containing block). Если такого предка нет — relative to initial containing block (viewport в большинстве случаев).

.card {
  position: relative;
}

.badge {
  position: absolute;
  top: 8px;
  right: 8px;
  /* позиционируется относительно .card */
}

fixed

Позиционируется относительно viewport и не прокручивается со страницей. Вырывается из потока. Используется для хедеров, тостов, модальных оверлеев.

.header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 64px;
  z-index: 100;
  background: white;
}

sticky

Гибрид relative и fixed: элемент ведёт себя как relative до достижения порогового значения прокрутки, затем «прилипает» и ведёт себя как fixed — но только в пределах своего scroll container (родителя с overflow). После выхода из этого контейнера элемент уходит вместе с ним.

.table-header {
  position: sticky;
  top: 0;       /* прилипает к верху при прокрутке */
  z-index: 10;
  background: white;
}

.sidebar {
  position: sticky;
  top: 80px;    /* учитываем высоту фиксированного хедера */
  align-self: start; /* для grid/flex — не растягивать по высоте */
}

Сводная таблица

/* static   — в потоке, смещения не работают */
/* relative — в потоке, смещается визуально, creating block для absolute */
/* absolute — вне потока, relative to nearest positioned ancestor */
/* fixed    — вне потока, relative to viewport */
/* sticky   — в потоке / фиксируется при прокрутке в пределах scroll container */

Подводные камни

  • Забытый relative на родителеabsolute-элемент уходит к viewport или нежелательному предку, если ни у одного родителя нет position: relative.
  • sticky не работает — самая частая причина: у родителя задан overflow: hidden или overflow: auto. Scroll container и sticky-элемент должны находиться в одном контексте прокрутки.
  • fixed и transform — если у предка задан transform, filter или perspective, position: fixed позиционируется относительно этого предка, а не viewport. Известная ловушка при анимации родительского контейнера.
  • z-index без stacking contextz-index работает только на позиционированных элементах (relative/absolute/fixed/sticky). Без явного создания stacking context порядок наложения может быть неожиданным.
  • absolute вырывает элемент из потока — соседи не «видят» его; он может перекрывать текст или другие элементы без видимых причин.
  • sticky и align-self: stretch — в grid-контейнере по умолчанию sticky-элемент растягивается по высоте ячейки и не прокручивается. Нужно задать align-self: start.
  • Скролл-контейнер для sticky должен иметь прокручиваемый контент — если родитель не переполняется, sticky ведёт себя как relative.

Common mistakes

  • Смешивать «position в CSS» с похожим механизмом без критерия выбора.
  • Игнорировать риск: неверно оценить границы применения темы «position в CSS» и получить хрупкое решение.
  • Показывать только синтаксис и не объяснять поведение в runtime или сборке.

What the interviewer is testing

  • Объясняет отличия static, relative, absolute, fixed и sticky для потока и containing block.
  • Показывает на примере, как работает: позиционирование меняет расчет смещения и иногда создает новый контекст наложения; absolute ищет ближайший позиционированный containing block, а sticky переключается между потоком и фиксацией в пределах контейнера прокрутки.
  • Называет production-нюанс и граничный случай для темы «position в CSS».

Sources

Related topics