← Назад к вопросам

Как работает Position: Absolute внутри Position: Absolute?

1.3 Junior🔥 151 комментариев
#HTML и CSS

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как работает Position: Absolute внутри Position: Absolute

Это один из самых запутанных аспектов CSS позиционирования. Ключевой момент: position: absolute позиционируется относительно ближайшего позиционированного предка, а не обязательно относительно непосредственного родителя.

Концепция Containing Block

В CSS существует понятие «containing block» — блок, относительно которого позиционируется элемент. Для position: absolute это ближайший предок с position, отличным от static:

<div class="outer">                   <!-- position: static (не позиционирован) -->
  <div class="positioned">            <!-- position: absolute или relative -->
    <div class="inner"></div>         <!-- position: absolute -->
  </div>
</div>

Элемент .inner позиционируется относительно .positioned, а не .outer.

Примеры

Абсолютный внутри абсолютного

<style>
  .outer {
    position: absolute;
    top: 10px;
    left: 10px;
    width: 200px;
    height: 200px;
    background: blue;
  }
  
  .inner {
    position: absolute;
    top: 20px;      /* 20px от верхнего края .outer */
    left: 30px;     /* 30px от левого края .outer */
    width: 100px;
    height: 100px;
    background: red;
  }
</style>

<div class="outer">
  <div class="inner"></div>
</div>

В этом примере:

  • .outer позиционируется 10px от верхнего левого угла viewport
  • .inner позиционируется 20px от верхнего края .outer и 30px от левого края .outer
  • Итоговая позиция .inner: top: 30px (10+20), left: 40px (10+30) от viewport

Абсолютный внутри статичного

<style>
  .outer {
    position: static;  /* Не позиционирован! */
    width: 300px;
    height: 300px;
    background: gray;
  }
  
  .middle {
    position: absolute;
    top: 10px;
    left: 10px;
    width: 200px;
    height: 200px;
    background: blue;
  }
  
  .inner {
    position: absolute;
    top: 20px;
    left: 20px;
    width: 100px;
    height: 100px;
    background: red;
  }
</style>

<div class="outer">
  <div class="middle">
    <div class="inner"></div>
  </div>
</div>

Внимание: .inner позиционируется относительно .middle, а не .outer, потому что .middle имеет position: absolute.

Позиционирование при отсутствии позиционированного предка

<style>
  .outer {
    position: static;
  }
  
  .middle {
    position: static; /* Тоже не позиционирован */
  }
  
  .inner {
    position: absolute;
    top: 0;
    left: 0;
    /* Позиционируется относительно body/html, т.е. viewport */
  }
</style>

<div class="outer">
  <div class="middle">
    <div class="inner"></div>
  </div>
</div>

Если нет позиционированного предка, position: absolute позиционируется относительно корневого элемента (html/body).

Важные свойства, создающие контекст позиционирования

Не только position создаёт containing block. Есть другие CSS свойства:

<style>
  .outer {
    /* Все эти свойства создают containing block для position: absolute */
    transform: translate(0, 0);        /* или любое другое значение */
    filter: blur(0);                   /* или любой другой фильтр */
    will-change: transform;            /* или другие значения */
    perspective: 1000px;
    opacity: 0.9;                      /* < 1 создаёт stacking context */
  }
  
  .inner {
    position: absolute;
    top: 0;
    left: 0;
  }
</style>

Осторожно: родитель со transform или filter становится containing block, хотя вы этого не ожидали!

Практический пример: Модальное окно

<style>
  .modal-overlay {
    position: fixed;      /* Фиксирует блок, создаёт containing block */
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.5);
  }
  
  .modal-content {
    position: absolute;   /* Позиционируется относительно .modal-overlay */
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 500px;
    height: 300px;
    background: white;
    border-radius: 8px;
  }
  
  .modal-header {
    position: absolute;   /* Позиционируется относительно .modal-content */
    top: 0;
    left: 0;
    right: 0;
    height: 40px;
    background: #f0f0f0;
  }
  
  .modal-close {
    position: absolute;   /* Позиционируется относительно .modal-header */
    top: 10px;
    right: 10px;
    cursor: pointer;
  }
</style>

Отладка с помощью DevTools

В браузере можно инспектировать containing block:

const el = document.querySelector('.inner');
const offsets = el.offsetParent; // Элемент, относительно которого позиционируется
console.log(offsets); // Показывает offsetParent

Рекомендации

  • Используйте position: relative на родителе, если хотите явно создать containing block
  • Помните о transform — он создаёт контекст позиционирования, хотя не меняет позицию
  • Проверяйте через DevTools, какой родитель является containing block
  • Избегайте глубокой вложенности абсолютного позиционирования — это усложняет отладку
  • Используйте position: fixed для модальных окон вместо вложенного абсолютного