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

Как создать контекст позиционирования?

2.0 Middle🔥 141 комментариев
#JavaScript Core

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

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

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

Как создать контекст позиционирования?

Контекст позиционирования (Stacking Context) — это трёхмерное концептуальное представление HTML-элементов по оси Z, которое определяет порядок их отрисовки. Это одна из самых запутанных частей CSS, потому что контекст позиционирования создаётся не только через z-index, но и через множество других свойств. Непонимание этого механизма приводит к неожиданным проблемам с наложением элементов.

Что такое контекст позиционирования?

В простых словах, контекст позиционирования — это группа элементов, внутри которой z-index значения считаются локально, а не глобально. Если элемент создаёт новый контекст, то все его дочерние элементы не могут быть выше элементов вне этого контекста, независимо от z-index значения.

/* Классический пример проблемы */
.parent {
  position: relative;
  z-index: 1;  /* Создаёт контекст позиционирования! */
}

.child {
  position: relative;
  z-index: 9999;  /* Это НЕ поможет! Child всё равно будет под modal */
}

.modal {
  position: fixed;
  z-index: 10;  /* Выше чем parent контекст */
}

/* Результат: modal будет выше child, хотя у child z-index: 9999 */

Способы создания контекста позиционирования

1. z-index с позиционированием

Этот способ создаёт новый контекст, но ТОЛЬКО если элемент позиционирован:

.element {
  position: relative; /* или absolute, fixed, sticky */
  z-index: 1;  /* Создаёт контекст */
}

/* Это НЕ создаёт контекст */
.static-element {
  position: static;
  z-index: 1;  /* z-index игнорируется! */
}

2. opacity меньше 1

Любой элемент с opacity < 1 создаёт новый контекст:

.transparent {
  opacity: 0.99;  /* Даже 0.99! */
  /* Новый контекст создан, даже без z-index */
}

Это частая причина неожиданного поведения!

3. Transform, filter, backdrop-filter

.element {
  transform: scale(1.1);  /* Создаёт контекст */
  /* или */
  filter: blur(5px);  /* Создаёт контекст */
  /* или */
  backdrop-filter: blur(10px);  /* Создаёт контекст */
}

4. mix-blend-mode

.blended {
  mix-blend-mode: multiply;  /* Любой режим создаёт контекст */
}

5. Flex и Grid контейнеры

.flex-container {
  display: flex;
  z-index: 1;  /* Flex + z-index = новый контекст */
}

.grid-container {
  display: grid;
  z-index: auto;  /* Даже с z-index: auto! */
}

6. Другие свойства

.element {
  /* will-change создаёт контекст */
  will-change: transform;
  
  /* contain создаёт контекст */
  contain: layout;
  
  /* isolation: isolate явно создаёт контекст */
  isolation: isolate;
  
  /* mask-image создаёт контекст */
  mask-image: url(#mask);
}

Полный список свойств, создающих контекст

  1. position (relative, absolute, fixed, sticky) + z-index (не auto)
  2. opacity < 1
  3. transform, filter, backdrop-filter
  4. mix-blend-mode (не normal)
  5. clip-path
  6. mask, mask-image, mask-border
  7. will-change
  8. contain: layout, paint, strict
  9. isolation: isolate
  10. flex-container или grid-container + z-index (не auto)
  11. perspective
  12. clip-path
  13. -webkit-* префиксные свойства

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

<div class="page-content">
  <div class="card" style="position: relative; z-index: 10;">
    <!-- Card content -->
  </div>
</div>

<div class="modal" style="position: fixed; z-index: 100;">
  <!-- Modal content -->
</div>

Проблема: если .page-content имеет opacity < 1, то он создаст контекст, и modal всё равно будет выше card, что хорошо.

.page-content {
  opacity: 0.9;  /* Создаёт контекст */
}

.card {
  position: relative;
  z-index: 10;  /* Локальный z-index внутри контекста */
}

.modal {
  position: fixed;
  z-index: 100;  /* Глобальный z-index */
  /* Успешно выше всего, потому что находится ВНЕ контекста */
}

Отладка контекстов

// Chrome DevTools помогает видеть z-index
// Правый клик на элемент -> Inspect -> Elements tab
// Видно все родительские контексты и их z-index

// Также можно использовать:
const getStackingContext = (el) => {
  const style = window.getComputedStyle(el);
  return {
    zIndex: style.zIndex,
    position: style.position,
    opacity: style.opacity,
    transform: style.transform,
    filter: style.filter,
  };
};

Лучшие практики

  1. Избегай множественных контекстов — логируй которые элементы их создают
  2. Используй isolation: isolate — явно обозначай контексты
  3. Не полагайся только на z-index — помни о других свойствах
  4. Структурируй контексты иерархически — модали в конце DOM
  5. Документируй z-index значения — создай таблицу слоёв
/* Переменные для z-index */
:root {
  --z-dropdown: 10;
  --z-sticky: 20;
  --z-fixed: 30;
  --z-modal-backdrop: 40;
  --z-modal: 50;
  --z-popover: 60;
  --z-tooltip: 70;
}

.modal {
  z-index: var(--z-modal);
}

Вывод

Контекст позиционирования — это не просто z-index. Это сложный механизм, который создаётся множеством свойств CSS. Главное помнить: элемент, создавший контекст, определяет максимальный z-index всех своих дочерних элементов. Понимание этого механизма критично для правильного управления наложением элементов в сложных интерфейсах.