Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Позиционирование

Обычно элементы стоят в потоке документа: каждый следующий блок идёт под предыдущим, строчные элементы — друг за другом в строке. Свойство position позволяет сдвинуть элемент, наложить его поверх других или прикрепить к краю окна.

Значения position

ЗначениеЧто делает
staticОбычное место в потоке. Значение по умолчанию
relativeСдвиг относительно своего обычного места
absoluteЭлемент выходит из потока и ставится по координатам внутри родителя
fixedПрикреплён к окну браузера и не прокручивается
stickyЕдет вместе со страницей, а у края окна «прилипает»

Координаты задают свойства top, right, bottom и left — расстояние от соответствующего края. У static они не действуют.

relative — сдвиг на месте

Элемент с position: relative сдвигается, но его прежнее место остаётся занятым, и соседи не двигаются:

<style>
  .box { padding: 8px; background: lavender; margin-bottom: 4px; }
  .moved { position: relative; top: 10px; left: 40px; background: gold; }
</style>
 
<div class="box">Первый</div>
<div class="box moved">Сдвинут на 10px вниз и 40px вправо</div>
<div class="box">Третий остался на месте</div>

Жёлтый блок наехал на третий: для остальных элементов он по-прежнему стоит на старом месте.

absolute — по координатам внутри родителя

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

<style>
  .card { position: relative; padding: 16px; background: whitesmoke; }
  .badge { position: absolute; top: 8px; right: 8px; padding: 2px 8px; background: crimson; color: white; }
</style>
 
<div class="card">
  <span class="badge">Новинка</span>
  Карточка товара. Метка прижата к правому верхнему углу.
</div>

Так делают значки, кнопки «закрыть», подписи поверх картинок. Прикрепить элемент к блоку, внутри которого он не лежит, позволяет привязка к якорю — урок «Привязка к якорю».

inset — все стороны сразу

Свойство inset — сокращение для четырёх координат. inset: 0 растягивает абсолютный элемент на весь родитель — удобно для затемняющего слоя:

<style>
  .photo { position: relative; height: 100px; background: steelblue; }
  .shade { position: absolute; inset: 0; background: rgb(0 0 0 / 0.4); color: white; padding: 12px; }
</style>
 
<div class="photo">
  <div class="shade">Слой поверх всего блока</div>
</div>

fixed и sticky

fixed прикрепляет элемент к окну: так делают кнопку «наверх» или чат в углу. sticky держит элемент на месте, пока его контейнер прокручивается. Прокрутите список в примере:

<style>
  .list { height: 140px; overflow: auto; border: 1px solid silver; }
  .list h3 { position: sticky; top: 0; margin: 0; padding: 6px 8px; background: lightskyblue; }
  .list p { margin: 0; padding: 6px 8px; }
</style>
 
<div class="list">
  <h3>Буква А</h3><p>Анна</p><p>Антон</p><p>Арсений</p>
  <h3>Буква Б</h3><p>Борис</p><p>Богдан</p><p>Белла</p>
  <h3>Буква В</h3><p>Вера</p><p>Виктор</p>
</div>

Для sticky обязательно указать хотя бы одну координату, например top: 0, — иначе прилипать некуда.

Частая ошибка

Если ни у одного предка нет position, абсолютный элемент отсчитывает координаты от всей страницы и улетает в её угол:

<style>
  .card { padding: 16px; background: whitesmoke; margin-top: 40px; }
  .badge { position: absolute; top: 8px; right: 8px; background: crimson; color: white; }
</style>
 
<div class="card">
  <span class="badge">Где я?</span>
  У карточки нет position: relative.
</div>

Метка оказалась в углу всего примера, а не карточки. Добавьте родителю position: relative.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.