position в CSS: relative, absolute, fixed и sticky на примерах

опубликовано
обновлено
читать
≈ 6 мин
автор
среда и версия
CSS; пример и три правки проверены в HTML/CSS-песочнице Koddo (Chromium) 20 октября 2026.

Значок «хит» должен сидеть в углу карточки, а улетает в угол страницы. Шапку хочется закрепить сверху, а она уезжает при прокрутке. Оба случая решает одно свойство — position, если знать, от чего каждое его значение отсчитывает top, right, bottom и left.

position выбирает, как элемент встаёт на странице: static — в обычном потоке, relative — со сдвигом от своего места, absolute — от ближайшего предка с position, fixed — от окна, sticky — как обычный, пока прокрутка не доведёт его до края. Разберём все пять на одной странице меню кофейни.

Пример: значок, липкая шапка и кнопка в углу

Открой пример в песочнице HTML/CSS ссылкой под вторым блоком: разметка попадёт во вкладку index.html, стили — в styles.css. Прокрути результат: шапка останется наверху, кнопка «позвонить» — в правом нижнем углу, а значок «хит» уедет вместе со своей карточкой.

HTML:

<header class="top">Кофейня «Зерно» · меню</header>
<main class="menu">
  <article class="item">
    <span class="badge">хит</span>
    <h2>Капучино</h2>
    <p>Двойной эспрессо и молоко.</p>
  </article>
  <article class="item">
    <h2>Раф</h2>
    <p>Сливки, ваниль и эспрессо.</p>
  </article>
  <article class="item">
    <h2>Какао</h2>
    <p>Горячий шоколад с корицей.</p>
  </article>
  <article class="item">
    <h2>Чай</h2>
    <p>Чёрный, зелёный или травяной.</p>
  </article>
</main>
<a class="call" href="#">позвонить</a>

CSS:

body {
  margin: 0;
  font-family: system-ui, sans-serif;
}

.top {
  position: sticky;
  top: 0;
  z-index: 1;
  padding: 0.75rem 1rem;
  background: #3b2a20;
  color: #fff8ef;
}

.menu {
  display: grid;
  gap: 1rem;
  padding: 1rem;
}

.item {
  position: relative;
  min-height: 140px;
  padding: 1rem;
  border: 1px solid #e3d6c8;
  border-radius: 0.75rem;
  background: #ffffff;
}

.badge {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  padding: 0.125rem 0.5rem;
  border-radius: 999px;
  background: #ff006e;
  color: #ffffff;
  font-size: 0.875rem;
}

.call {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  padding: 0.75rem 1.25rem;
  border-radius: 999px;
  background: #2e7d32;
  color: #ffffff;
  text-decoration: none;
}
position / 01

У каждого значения своя точка отсчёта

Точки отсчёта absolute, fixed и sticky в примере кофейниШаг 1: значок «хит» с position: absolute встаёт в 12 пикселях от верхнего и правого края карточки, потому что у карточки position: relative. Шаг 2: кнопка «позвонить» с position: fixed держится в 16 пикселях от правого нижнего угла окна и не уезжает при прокрутке. Шаг 3: шапка с position: sticky и top: 0 едет вместе со страницей, пока не упрётся в верх окна, а потом остаётся на месте. Если у предка нет position, absolute отсчитывает от угла страницы.01 / absolute в relative02 / fixed03 / stickyкарточкаposition: relativeхитпозвонитьшапкаtop и right — от угла карточки,у которой есть positionот края окна; при прокруткекнопка остаётся на местеедет со страницей, покане упрётся в top: 0Нет предка с position — absolute отсчитывает от угла страницы.
absolute отсчитывает от ближайшего предка с position, fixed — от окна, а sticky ведёт себя как обычный блок, пока прокрутка не доведёт его до порога из top.

static и relative: обычный поток и сдвиг

static. Значение по умолчанию: элемент стоит в потоке, где ему положено, а top и left на него не действуют.

relative. Элемент остаётся в потоке, но его можно сдвинуть от своего места: top: 10px опустит его на 10 пикселей. Место, которое он занимал, при этом остаётся пустым, соседи не сдвигаются. Чаще relative ставят без всяких сдвигов — ради опоры для absolute, как у карточки в примере.

absolute: от ближайшего предка с position

Элемент с position: absolute выпадает из потока: остальные элементы ведут себя так, будто его нет. top, right, bottom и left отсчитываются от ближайшего предка, у которого position не static. У значка «хит» это карточка с position: relative, поэтому значок сидит в 12 пикселях от её верхнего и правого края, считая изнутри рамки, и ездит вместе с ней.

Если такого предка нет, absolute отсчитывает от начального блока страницы — прямоугольника размером с окно в самом верху документа. Тогда значок окажется в правом верхнем углу страницы, далеко от своей карточки.

Растянуть элемент на всего родителя помогает inset: 0 — это сокращение для top, right, bottom и left со значением 0. Так делают затемнение поверх картинки или кликабельную область на всю карточку.

fixed и sticky: от окна

fixed. Отсчитывает от окна браузера и не двигается при прокрутке: так сделаны кнопка «позвонить», чат в углу, всплывающее окно. Из потока он выпадает так же, как absolute.

sticky. Гибрид: пока элемент в поле зрения, он стоит в потоке как обычный, а когда прокрутка доводит его до порога, держится на месте. Порог задают через top, bottom, left или right: у шапки top: 0, то есть верхний край окна. Держится он только в пределах своего родителя: когда родитель уедет, уедет и sticky.

z-index: кто кого перекрывает

Элементы с position рисуются поверх обычных, а между собой — в порядке разметки: кто ниже в HTML, тот и сверху. Карточки в примере тоже с position, и они идут после шапки, поэтому при прокрутке без z-index наехали бы на неё. z-index: 1 у шапки поднимает её выше.

У z-index есть ловушка — контекст наложения. Если у родителя есть position и свой z-index, его дети сравниваются только друг с другом: даже z-index: 9999 не поднимет ребёнка выше соседей его родителя. Если элемент упорно остаётся снизу, смотри на z-index его предков.

Шпаргалка по position

ЗначениеВ потоке?От чего считает top и leftДля чего
staticдане считаетобычный поток, по умолчанию
relativeда, место остаётсяот своего местанебольшой сдвиг, опора для absolute
absoluteнетот ближайшего предка с positionзначки, подписи, затемнение поверх
fixedнетот окнакнопка в углу, чат, всплывающее окно
stickyдаот края прокрутки, после порогалипкая шапка, заголовки таблиц

Почему не работает: частые ошибки

absolute улетает в угол страницы. У родителя нет position. Добавь ему position: relative.

sticky не прилипает. Чаще всего не задан порог, top: 0. Вторая причина — у предка overflow: hidden или auto: тогда элемент прилипает внутри этого предка, а он сам не прокручивается.

fixed прокручивается вместе со страницей. Если у предка есть transform или filter, fixed считает уже от этого предка, а не от окна. Перенеси элемент выше по разметке.

z-index не работает. У элемента нет position, и z-index на него не действует. Исключение — элементы внутри Flexbox и Grid: там z-index работает и без position.

Три правки, чтобы закрепить

Открой пример в песочнице и перед каждой правкой предскажи результат:

  1. Убери у .item строку position: relative. Значок «хит» пропадёт. Он улетел в правый верхний угол страницы, потому что отсчитывать его больше не от чего, и спрятался под шапкой: у неё z-index: 1.
  2. Убери у .top строку top: 0. Шапка перестанет прилипать и уедет при прокрутке: без порога sticky не знает, где остановиться.
  3. Убери у .top строку z-index: 1 и прокрути результат. Карточки поедут поверх шапки: они тоже с position и стоят в разметке ниже.

Потренировать absolute без подсказок можно в игре «Повтори макет»: на уровне «Глаза» зрачки ставят как раз внутри глаза с position: relative. А выравнивать без позиционирования помогают статьи про выравнивание по центру и Flexbox.

Источники