Как наложить элементы друг на друга с помощью CSS

Наложить один элемент поверх другого в CSS можно через position: absolute или общую ячейку Grid. Порядок слоев меняет z-index, а Grid помогает сохранить текст внутри адаптивной карточки. Разберите примеры для блоков, изображения и оверлея, который не ломает узкий экран.

Наложение через position: absolute

Абсолютный элемент выпадает из обычного потока документа. Браузер позиционирует его относительно ближайшего предка с любым значением position, кроме static. Если такого предка нет, отсчет идет от начального содержащего блока.

.child {
  position: absolute;
  top: 0;
  left: 0;
}

В демо блок закрепляется у верхнего левого края содержащего блока.

Область позиционирования задает родитель с position: relative. Родитель останется в потоке, а абсолютный ребенок сможет перекрывать соседей и не будет зависеть от угла страницы.

.parent {
  position: relative;
}

.child {
  position: absolute;
  top: 0;
  left: 0;
}

В демо абсолютный блок остается привязанным к родителю при добавлении соседних элементов.

Два дочерних блока можно поместить в одну область родителя и задать им размеры. Свойство top задает общий верхний край, а left меняет положение каждого слоя.

<div class="parent">
  <h2>Parent</h2>
  <div class="child child-1">
    <h2>Child 1</h2>
  </div>
  <div class="child child-2">
    <h2>Child 2</h2>
  </div>
</div>
.parent {
  position: relative;
  min-height: 150px;
}

.child {
  position: absolute;
  top: 20px;
  width: 140px;
  height: 90px;
  padding: 12px;
  box-sizing: border-box;
  color: white;
}

.child-1 {
  left: 20px;
  background: #2878c8;
}

.child-2 {
  left: 100px;
  background: #d85b48;
}

В демо цветные блоки имеют общую область и перекрываются на 60 пикселей.

Наложение элементов в CSS Grid

Grid позволяет назначить нескольким элементам одну область сетки. Такой подход сохраняет слои внутри раскладки и учитывает содержимое общей ячейки.

CSS Grid поддерживается всеми актуальными браузерами. Для наложения задайте одинаковый grid-area нескольким элементам.

.parent {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto auto;
}

.child {
  grid-area: 1 / 1;
}

В демо элементы занимают одну ячейку сетки и располагаются слоями.

Выравнивание внутри общей области задают через place-items у сетки или place-self у отдельного элемента. Отступ-подпорка вроде margin-left: 200px здесь не нужна.

.parent {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto auto;
  place-items: start;
}

.child {
  grid-area: 1 / 1;
}

.child-2 {
  place-self: end;
}

В демо второй блок выравнивается внутри общей области без искусственного отступа.

Автоматический размер строки Grid учитывает содержимое общей ячейки, если строка не ограничена фиксированной высотой. Длинный текст увеличит родителя. Абсолютный элемент такого участия не принимает.

Как управлять порядком слоев через z-index

Когда элементы пересекаются, браузер обычно показывает сверху тот, который идет позже в DOM. Свойство z-index меняет этот порядок в одном контексте наложения.

.parent {
  position: relative;
}

.child-1,
.child-2 {
  position: absolute;
  inset: 0;
}

.child-1 {
  z-index: 2;
}

.child-2 {
  z-index: 1;
}

Чем больше значение z-index, тем выше слой внутри одного контекста. Свойство работает у позиционированных элементов, а также у элементов Grid и Flexbox.

Контекст наложения ограничивает сравнение значений. Его создают, например, элемент с opacity меньше 1, свойством transform или isolation: isolate. Потомок останется под соседним контекстом с более высоким уровнем даже при z-index: 999.

Как положить текст поверх изображения

Для карточки с изображением задайте контейнеру сетку. Картинка и оверлей поместятся в одну область, а текст сохранит участие в раскладке.

<figure class="hero">
  <img src="image.jpg" alt="Горный пейзаж">
  <div class="hero__overlay">
    <h2>Поход в горы</h2>
    <p>Маршрут для выходных.</p>
  </div>
</figure>
.hero {
  display: grid;
  position: relative;
  width: 100%;
  max-width: 720px;
  margin: 0;
  background: #222;
}

.hero > * {
  grid-area: 1 / 1;
}

.hero img {
  display: block;
  width: 100%;
  height: auto;
  object-fit: cover;
}

.hero__overlay {
  z-index: 1;
  display: grid;
  place-content: center;
  align-self: stretch;
  min-width: 0;
  padding: 5%;
  box-sizing: border-box;
  color: white;
  background: rgb(0 0 0 / 45%);
  text-align: center;
}

.hero__overlay h2,
.hero__overlay p {
  margin: 0.4em 0;
}

@media (max-width: 420px) {
  .hero__overlay {
    place-content: end center;
    padding: 8%;
    font-size: 0.9rem;
  }
}

Замените image.jpg путем к своему изображению. Grid учитывает высоту текста в общей строке, поэтому увеличенный шрифт не уходит за границы карточки. На узком экране медиазапрос переносит текст ближе к нижнему краю и сохраняет затемнение.

Когда подходят отрицательный margin и transform

Отрицательный внешний отступ сдвигает элемент к соседнему блоку и сохраняет его участие в потоке. Используйте такой прием для небольшого декоративного выступа, когда размер родителя должен учитывать элемент.

.badge {
  margin-left: -20px;
}

Трансформация меняет визуальное положение элемента без перерасчета места в потоке. Берите ее для точного декоративного сдвига или анимации.

.badge {
  transform: translate(20px, -10px);
}
СпособВыпадает из потокаВлияет на размер родителяАдаптивностьКогда выбирать
position: absoluteДаНетНужны относительные размеры и контроль переполненияОверлей, бейдж, текст поверх изображения
CSS GridНетДаАвтоматические треки учитывают содержимоеСлои внутри общей раскладки
Отрицательный margin или transformНетMargin влияет, transform не влияетПодходит для небольшого сдвигаДекоративный выступ или точная коррекция

Почему не работает z-index

Проблема обычно связана с типом элемента, контекстом наложения или обрезкой содержимого. Проверьте эти причины по порядку.

  • Элемент не поддерживает z-index в текущей раскладке. Для обычного непозиционированного блока задайте position: relative, absolute или другое значение кроме static. Исключение составляют элементы Grid и Flexbox.
  • z-index потомка ограничен контекстом предка. Если родитель создает контекст через opacity, transform, isolation или другой механизм, сравнивайте z-index самих родителей. Значение потомка не выйдет за пределы своего контекста.
  • Оверлей обрезается. Родитель обрезает выступающую часть дочернего элемента при overflow: hidden. Уберите это ограничение или разместите слой внутри нужной области.
  • Элементы не пересекаются. Проверьте top, left, inset и общую ячейку Grid. Один только z-index не меняет геометрию блока.

Какой способ выбрать для задачи

Точный оверлей поверх родителя проще собрать через position: absolute. Привяжите оверлей к родителю с помощью position: relative у контейнера. Размеры слоя задайте в процентах или растяните его через inset: 0.

Когда текст должен влиять на высоту карточки, выбирайте Grid. Для небольшого декоративного сдвига хватит отрицательного margin или transform.

Совет от нашей редакции: сначала соберите структуру через Grid или обычный поток, а абсолютное позиционирование оставьте для слоев, которые действительно должны перекрывать соседей.

Комментарии

Оставьте свой комментарий
Пока никто не оставил комментариев