Позиционирование элементов - свойство Position

Свойство position является одним из базовых CSS-свойств, которое необходимо понять при изучении вёрстки. В этой статье мы разберём его подробно на примерах.

Свойство Position

Свойство position определяет позиционирование элемента и влияет на соседние и дочерние элементы

Свойство position имеет 5 основных значений

  1. static - статический не позиционированный элемент
  2. relative - относительно позиционированный элемент
  3. absolute - абсолютно позиционированный элемент
  4. sticky - прилипающий позиционированный элемент
  5. fixed - фиксированный позиционированный элемент

По-умолчанию у всех элементов свойство position имеет значение static - такие элементы называются не позиционированными

Свойство position также влияет на некоторые другие свойства элемента - при значении static (то есть пока элемент является не позиционированным) не работают свойства top, left, right, bottom, z-index

Чтобы элемент стал позиционированным, ему необходимо назначить свойство position c любым из следующих значений - relative, absolute, sticky, fixed

Ниже будем рассматривать каждое из значений отдельно

Для наглядности сверстаем несколько элементов вложенных друг в друга.

Элемент <body> имеет белый фон и содежит серый элемент, который содержит в себе дочерний жёлтый элемент, который, в свою очередь, содержит в себе 3 дочерних элемента - красный, зелёный и синий

<body>
  <div class="box box__gray">
    <div class="box box__yellow">
      <div class="box box__red"></div>
      <div class="box box__green"></div>
      <div class="box box__blue"></div>
    </div>
  </div>
</body>

Зададим начальные стили

body {
  padding: 30px;
}
.box {
  border: 2px dashed #111;
  padding: 30px;
}
.box__gray {
  width: 500px;
  height: 500px;
  background: rgba(221,221,221,0.8);
}
.box__yellow {
  width: 400px;
  height: 400px;
  background: rgba(255,209,102,0.8);
}
.box__red {
  background: rgba(239,71,111,0.8);
  width: 150px;
  height: 150px;
}
.box__green {
  background: rgba(6,214,160,0.8);
  width: 100px;
  height: 100px;
}
.box__blue {
  background: rgba(17,138,178,0.8);
  width: 50px;
  height: 50px;
}

Для примеров будем задавать элементам инлайн-стили

На данный момент все элементы по-умолчанию имеют свойство position со значением static и являются не позиционированными.

Элементы устанавливаются друг за другом в том порядке, в каком они находятся в HTML-разметке

1



Position Static

Элемент является статическим не позиционированным

Элементу нельзя задать свойства top, left, right, bottom, z-index - они будут проигнорированы

Элемент виден для соседних элементов и занимает определенное пространство между ними

Границы элемента не видны для дочерних элементов, у который свойство position имеет одно из следующих значений - absolute, sticky, fixed.

Попробуем задать зелёному элементу свойства top и left

<body>
  <div class="box box__gray">
    <div class="box box__yellow">
      <div class="box box__red"></div>
      <div class="box box__green" style="top: 30px; left: 30px;"></div>
      <div class="box box__blue"></div>
    </div>
  </div>
</body>

1

Зелёный элемент остается на месте и никак не реагирует на указанные свойства top и left, так как зелёный элемент является не позиционированным



Position Relative

Элемент является относительно позиционированным

Элементу можно задавать свойства top, left, right, bottom, z-index. При указании свойств top, left, right, bottom элемент будет смещаться на указанное значение от своего текущего положения

Элемент виден для соседних элементов и занимает определенное пространство между ними

Границы элемента видны для дочерних элементов, у который свойство position имеет одно из следующих значений - static, relative, absolute, sticky

Зададим зелёному элементу position: relative; top: 30px; left: 30px;

<body>
  <div class="box box__gray">
    <div class="box box__yellow">
      <div class="box box__red"></div>
      <div class="box box__green" style="position: relative; top: 30px; left: 30px;"></div>
      <div class="box box__blue"></div>
    </div>
  </div>
</body>

2

Зелёный элемент теперь смещается на указанные 30px сверху и 30px слева от текущего положения, так как теперь он является позиционированным



Position Absolute

Элемент является абсолютно позиционированным

Элементу можно задавать свойства top, left, right, bottom, z-index

Если элементу не задавать свойства top, left, right, bottom, то элемент будет установлен на то место, где он бы находился при position: relative;, при этом не сохраняя свое пространство между соседними элементами

Элемент не виден для соседних элементов и не занимает пространство между ними

Границы элемента видны для дочерних элементов, у который свойство position имеет одно из следующих значений - static, relative, absolute, sticky

Зададим зелёному элементу position: absolute; top: 15px; left: 15px;

<body>
  <div class="box box__gray">
    <div class="box box__yellow">
      <div class="box box__red"></div>
      <div class="box box__green" style="position: absolute; top: 15px; left: 15px;"></div>
      <div class="box box__blue"></div>
    </div>
  </div>
</body>

3

Зелёный элемент больше не занимает пространство между соседними элементами и должен смещаться на указанные 15px сверху и 15px слева от ближайшего родительского позиционированного элемента, но такого родительского элемента у нас пока нет

Так как элемент <body>, серый и жёлтый элементы не позиционированы (то есть у них по-умолчанию установлено position: static), то зелёный элемент смещается от границ окна браузера

Чтобы зелёный элемент смещался от границ серого элемента, зададим серому элементу свойство position c любым значением, отличным от static

Зададим серому элементу position: relative;, что сделает его позиционированным

<body>
  <div class="box box__gray" style="position: relative;">
    <div class="box box__yellow">
      <div class="box box__red"></div>
      <div class="box box__green" style="position: absolute; top: 15px; left: 15px;"></div>
      <div class="box box__blue"></div>
    </div>
  </div>
</body>

4

Теперь зелёный элемент смещается на указанные 15px сверху и 15px слева от границ серого элемента, как от ближайшего родительского позиционированного элемента

Сделаем жёлтый элемент тоже позиционированным, для этого добавим ему position: relative;

<body>
  <div class="box box__gray" style="position: relative;">
    <div class="box box__yellow" style="position: relative;">
      <div class="box box__red"></div>
      <div class="box box__green" style="position: absolute; top: 15px; left: 15px;"></div>
      <div class="box box__blue"></div>
    </div>
  </div>
</body>

5

Теперь ближайшим родительским позиционированным элементом для зелёного элемента является жёлтый элемент, поэтому зелёный элемент теперь смещается на указанные 15px сверху и 15px слева от границ жёлтого элемента


К примеру, теперь мы хотим смещать зелёный элемент от нижней и правой границ жёлтого элемента. Попробуем добавить bottom: 15px; и right: 15px;

<body>
  <div class="box box__gray" style="position: relative;">
    <div class="box box__yellow" style="position: relative;">
      <div class="box box__red"></div>
      <div class="box box__green" style="position: absolute; top: 15px; left: 15px; bottom: 15px; right: 15px"></div>
      <div class="box box__blue"></div>
    </div>
  </div>
</body>

5

Но зелёный элемент остается на месте и по прежнему смещается от верхней и левой границ жёлтого элемента

Чтобы, все-таки, смещать зелёный элемент от нижней и правой границ жёлтого элемента, необходимо учитывать следующий нюанс - если одновременно заданы свойства left и right, то приоритет будет иметь свойство left, а свойство right будет игнорироваться. Тоже самое и со свойствами top и bottom - если они заданы одновременно, то приоритет имеет свойство top, а свойство bottom игнорируется

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

Удалим свойства top и left, чтобы остались только свойства bottom и right

<body>
  <div class="box box__gray" style="position: relative;">
    <div class="box box__yellow" style="position: relative;">
      <div class="box box__red"></div>
      <div class="box box__green" style="position: absolute; bottom: 15px; right: 15px;"></div>
      <div class="box box__blue"></div>
    </div>
  </div>
</body>

6

Теперь все работает корректно, и зелёный элемент смещается от нижней и правой границ жёлтого элемента


Для полной картины удалим оставшиеся свойства bottom и right

<body>
  <div class="box box__gray" style="position: relative;">
    <div class="box box__yellow" style="position: relative;">
      <div class="box box__red"></div>
      <div class="box box__green" style="position: absolute;"></div>
      <div class="box box__blue"></div>
    </div>
  </div>
</body>

8

Зелёный элемент устанавливается на то место, где он бы находился при position: relative;, но при этом не сохраняет свое пространство между соседними элементами


Рассмотрим пример, когда у зелёного элемента не заданы размеры. В таком случаем мы можем использовать свойства left/right и top/bottom одновременно

Сбросим у зелёного элемента ширину и высоту - width: auto; height: auto;, а также добавим top: 50px; left: 15px; bottom: 0px; right: 30px; одновременно

<body>
  <div class="box box__gray" style="position: relative;">
    <div class="box box__yellow" style="position: relative;">
      <div class="box box__red"></div>
      <div class="box box__green" style="width: auto; height: auto; position: absolute; top: 50px; left: 15px; bottom: 0px; right: 30px;"></div>
      <div class="box box__blue"></div>
    </div>
  </div>
</body>

10

Так как размеры у зелёного элемента теперь не указаны, мы используем свойства left/right и top/bottom одновременно, и зелёный элемент растягивается на всё пространство родительского жёлтого позиционированного элемента и смещается от его границ на указанные расстояния со всех сторон



Position Sticky

При прокрутке страницы или элемента с возможностью прокрутки, дочерний элемент со свойством position: sticky; прилипает на указанном расстоянии от границ родительского элемента

Подробнее про position: sticky; можно почитать в отдельной статье - Как закрепить блок при прокрутке страницы

Элемент является прилипающим позиционированным

Элементу можно задавать свойства top, left, right, bottom, z-index

Если элементу не задавать свойства top, left, right, bottom, то элемент будет вести себя как при position: relative;

Элемент виден для соседних элементов и занимает определенное пространство между ними

Границы элемента видны для дочерних элементов, у который свойство position имеет одно из следующих значений - static, relative, absolute, sticky

Зададим зелёному элементу position: sticky; top: 15px;, а также добавим больше синих элементов и установим для желтого элемента overflow: auto; padding-top: 0;

<body>
  <div class="box box__gray" style="position: relative;">
    <div class="box box__yellow" style="position: relative; overflow: auto; padding-top: 0">
      <div class="box box__red"></div>
      <div class="box box__green" style="position: sticky; top: 15px;"></div>
      <div class="box box__blue"></div>
      <div class="box box__blue"></div>
      <div class="box box__blue"></div>
      <div class="box box__blue"></div>
      <div class="box box__blue"></div>
      <div class="box box__blue"></div>
      <div class="box box__blue"></div>
      <div class="box box__blue"></div>
    </div>
  </div>
</body>

7

При прокрутке жёлтого элемента, зелёный элемент прилипает на расстоянии указанных 15px от верхней границы жёлтого элемента, при этом сохраняет определенное пространство между соседними элементами



Position Fixed

Элемент является фиксированным позиционированным

Элемент фиксируется и смещается на указанное расстояние от границ окна браузера, независимо от того, является ли его родительский элемент позиционированным или не позиционированным

Элементу можно задавать свойства top, left, right, bottom, z-index

Если элементу не задавать свойства top, left, right, bottom, то элемент будет установлен на то место, где он бы находился при position: relative;, при этом не сохраняя своё пространство между соседними элементами и при прокрутке будет зафиксирован именно на этом месте

Элемент не виден для соседних элементов и не занимает пространство между ними

Границы элемента видны для дочерних элементов, у который свойство position имеет одно из следующих значений - static, relative, absolute, sticky

Зададим зелёному элементу position: fixed; bottom: 15px; right: 15px, а также второй серый элемент, чтобы страницу можно было прокрутить

<body>
  <div class="box box__gray" style="position: relative;">
    <div class="box box__yellow" style="position: relative;">
      <div class="box box__red"></div>
      <div class="box box__green" style="position: fixed; right: 15px; bottom: 15px"></div>
      <div class="box box__blue"></div>
    </div>
  </div>
  <div class="box box__gray" style="position: relative;"></div>
</body>

9

Элемент фиксируется на растоянии указанных 15px снизу и 15px справа от границ окна браузера, независимо от того, что его родительский элемент является позиционированным


Рассмотрим пример, в котором сбросим высоту зелёного элемента, а ширину оставим и зафиксируем его по левой границе окна браузера

<body>
  <div class="box box__gray" style="position: relative;">
    <div class="box box__yellow" style="position: relative;">
      <div class="box box__red"></div>
      <div class="box box__green" style="height: auto; position: fixed; top: 0px; left: 0px; bottom: 0px;"></div>
      <div class="box box__blue"></div>
    </div>
  </div>
  <div class="box box__gray"></div>
</body>

11

Несмотря на то, что родительский жёлтый элемент является позиционированным, зелёный элемент фиксируется на указанных расстояниях от границ окна браузера. Так как мы указали нулевые расстояния, то зелёный элемент фиксируется вплотную, примыкая к границам окна браузера



Итоги

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

Буду рад, если статья оказалась полезной

Рекомендую также прочесть статью - Свойство z-index и контекст наложения

Спасибо за ваше внимание и уделённое время!



Полезные ссылки

Как закрепить блок при прокрутке страницы

Свойство z-index и контекст наложения

MDN Web Docs - Position