CSS-свойство position: разбираемся с позиционированием элементов

Перевод статьи «A painless guide to understanding CSS positioning».

Photo by Blue Bird from Pexels

Если вы хотите действительно хорошо овладеть CSS, очень важно разобраться в свойстве position. Но стоит учесть, что для начинающих эта тема может быть довольно сложной.

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

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

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

Поточная раскладка

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

CSS трактует каждый HTML-элемент как отдельный блок (возможно, вы слышали о понятии «блочная модель»). Элементы блочного уровня (заголовки, абзацы или блоки div) по умолчанию начинаются как бы с новой строки. А строчные (inline) элементы (например, изображения и элементы span), отображаются в строке вместе с другим контентом. Такое отображение элементов принято по умолчанию и называется нормальным потоком документа. Но CSS дает нам мощный инструмент для перезаписи нормального потока — свойство position.

Давайте рассмотрим, что оно делает.

Свойство position

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

Свойство position имеет пять возможных значений:

  1. static (статическое позиционирование)
  2. relative (относительное)
  3. absolute (абсолютное)
  4. fixed (фиксированное)
  5. sticky (липкое)

Мы разберем все 5 значений, но сначала обратим внимание на свойства расположения.

Свойства расположения

Само по себе свойство position не слишком-то много и может. Чтобы указать, где именно в документе нужно расположить элемент, мы используем свойства расположения (это не официальное название, это я их так называю). Этих свойств четыре:

  • top (верх)
  • left (слева)
  • right (справа)
  • bottom (низ)

Значения этих свойств определяют, насколько позиция элемента должна сместиться и в каком направлении (вверх, вниз, влево, вправо). Чуть позже мы все это разберем на примерах.

Значения свойства position

Статическое позиционирование

static — это дефолтное значение свойства position. Оно предполагает, что элементы на странице отображаются в нормальном потоке. Свойства top, left, bottom и right не влияют на элемент, имеющий position: static.

Несмотря на то, что это дефолтное значение, оно может задаваться явно. Например, когда вам нужно перезаписать значение position, установленное где-то еще (и унаследованное вашим элементом).

Давайте рассмотрим пример. На нем мы увидим, что указание position: static никак не влияет на отображение элемента.

<div class="parent-box">
  <div class="box-original">
    <div class="box-1"> </div>
  </div>

  <div class="box-original">
    <div class="box-2"> </div>
  </div>

  <div class="box-original">
    <div class="box-3"> </div>
  </div>
</div>

Здесь у нас три блока div, каждый из которых находится в родительском контейнере с классом box-original.

Давайте добавим position: static для div с классом box-2 и зададим также значения для свойств top и left.

.box-2 {
  position: static;
  top: 10px;
  left: 10px;
  border: 1px solid black;
  background-color: mediumpurple;
  width: 100px;
  height: 100px;
  text-align: center;
  display: inline-block;
  align-self: center;
  margin-left: -1px;
  margin-top: -1px;
}

Результат изменений:

See the Pen Static Positioning by Peter (@pin0s) on CodePen.

Как видите, несмотря на то, что мы задали свойства top и left, блок располагается в нормальном потоке.

Теперь вы знаете, что значение static является дефолтным для свойства position, а указание свойств расположения не сдвигает элементы, для которых указано position: static.

Относительное позиционирование

Относительное позиционирование означает, что элемент позиционируется относительно своей исходной позиции в нормальном потоке. Если просто задать элементу position: relative, ничего не произойдет. Для изменения позиции нужно задать свойства расположения.

В общем, если вы просто задаете элементу position: relative, он остается в нормальном потоке. Но при помощи свойств расположения вы можете его сдвинуть. Давайте рассмотрим пример.

Возьмем код из прошлого примера и заменим position: static на position: relative.

.box-2 {
  position: relative;
  top: 10px;
  left: 10px;
  border: 1px solid red;
  background-color: mediumpurple;
  width: 100px;
  height: 100px;
  text-align: center;
  align-self: center;
  margin-left: -1px;
  margin-top: -1px;
}

Результат:

See the Pen Relative Positioning by Peter (@pin0s) on CodePen.

Фиолетовый квадрат сдвинулся со своей нормальной позиции (обозначена серым квадратом). В этом примере задано смещение на 10px от верха и от левого края этого же элемента в дефолтном положении (т. е. смещение вниз и вправо).

Элемент при этом остается в нормальном потоке документа, а сдвиг происходит относительно его исходной позиции. Запомните это: пригодится, когда мы будем разбирать следующие значения.

Абсолютное позиционирование

При абсолютном позиционировании элементы изымаются из нормального потока документа, а пространство, которое они занимали, больше не резервируется за ними. То есть их как бы вообще здесь нет.

Когда элементу задано позиционирование position: absolute, все остальные элементы ведут себя так, будто этого элемента вообще больше нет в документе. Поэтому для этого элемента не резервируется место поточной раскладке. Абсолютное позиционирование — мощный инструмент в деле перемещения элементов.

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

Это очень важный момент. Если ближайший родительский элемент не имеет указанного свойства position, элемент с абсолютным позиционированием будет позиционироваться относительно следующего в иерархии родительского элемента, имеющего это свойство. Если у элемента вообще не будет позиционированных предков, он будет позиционироваться относительно элемента html или viewport. Не зная этого, можно долго ломать голову, почему все работает не так, как задумано.

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

Вернемся к нашему примеру. Изменим свойство position второго блочного элемента на position: absolute. Прежде чем рассматривать результат, вернитесь к предыдущему пену и обратите внимание на позиционирование элемента parent-box.

.box-2 {
  position: absolute;
  top: 30px;
  left: 150px;
  border: 1px solid red;
  background-color: mediumpurple;
  width: 100px;
  height: 100px;
  text-align: center;
  align-self: center;
  margin-left: -1px;
  margin-top: -1px;
}

Результат изменений:

See the Pen Absolute Positioning by Peter (@pin0s) on CodePen.

Вы видите, что в документе не создалось пустого места для нашего элемента. Фактически это место схлопнулось, и другие элементы ведут себя так, будто на этом месте вообще ничего никогда не было. Так происходит потому, что наш элемент теперь позиционируется относительно элемента parent-box.

Photo by Blue Bird from Pexels

Фиксированное позиционирование

Фиксированное позиционирование работает подобно абсолютному. Оно удаляет элемент из нормального потока документа, причем под этот элемент в раскладке больше не отводится никакого места.

Элементы с фиксированным позиционированием позиционируются относительно viewport. (Viewport — это видимая пользователю область веб-страницы, то, что может увидеть пользователь, не прибегая к прокрутке, — MDN).

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

Давайте изменим позиционирование box-2 с position: absolute на position: fixed. Также мы изменим значение свойства top на 0 и удалим значение свойства left. Еще мы добавим несколько дополнительных блоков, чтобы увидеть эффект при прокрутке.

.box-2 {
  position: fixed;
  top: 0px;
  border: 1px solid red;
  background-color: mediumpurple;
  width: 100px;
  height: 100px;
  text-align: center;
  align-self: center;
  margin-left: -1px;
  margin-top: -1px;
}

Результат:

See the Pen Fixed Positioning by Peter (@pin0s) on CodePen.

Как видите, фиолетовый блок теперь зафиксирован вверху страницы. Мы добились такого эффекта, установив для него position: fixed и top: 0px.

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

Липкое позиционирование

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

Давайте рассмотрим новый пример. Мы зададим dt свойство position: sticky и top: 3px (т. е. смещение на 3px от верха страницы).

dt {
  background: #007FFF;
  border-bottom: 1px solid yellow;
  border-top: 1px solid yellow;
  color: yellow;
  margin: 0;
  padding: 2px 0 0 12px;
  position: sticky;
  top: 3px;
}

Попробуйте прокрутить страницу, и увидите, как работает липкое позиционирование.

See the Pen Sticky Positioning by Peter (@pin0s) on CodePen.

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

Работать с липким позиционированием надо осторожно, потому что не все браузеры его поддерживают (по крайней мере, на момент написания статьи). Проверить поддержку можно при помощи caniuse.com.

Где во всем этом место Z-индекса?

z-index — это CSS-свойство, позволяющее задавать порядок позиционированных элементов по оси z. Любой элемент, которому вы задали свойство position, отличное от static, может позиционироваться и по оси z.

Оси координат

В целом, z-index позволяет контролировать порядок расположения и, таким образом, перекрытие элементов. С его помощью вы определяете, какие элементы должны стоять на переднем плане, а какие — сзади.

Элементы с большим значением z-index отображаются перед элементами с меньшими значениями.

Рассмотрим пример. Я покажу, что при использовании z-index порядок элементов в html-разметке не имеет значения, мы можем сменить их позицию с передней на заднюю.

<div class="parent-box">

    <div class="box box-1">z-index:4</div>
    <div class="box box-2">z-index:1</div>
    <div class="box box-3">z-index:2</div>
    <div class="box box-4">z-index:5</div>
    <div class="box box-5">z-index:3</div>

</div>

Мы зададим каждому классу box позицию fixed, что позволит нам изменить z-index каждого из box-элементов.

Результат:

See the Pen Z-index by Peter (@pin0s) on CodePen.

Как видите, элементы с более высоким значением z-index идут на переднем плане, а с более низким — на заднем.

Заключение

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

Мы можем применять пять значений свойства position:

  • static
  • relative
  • absolute
  • fixed
  • sticky

Положение элемента задается при помощи свойств top, left, bottom и right. Значения этих свойств указывают, насколько должен сместиться элемент от указанной точки.

Если элемент позиционирован, причем значение position — не static, можно задавать положение этого элемента по оси z. Это делается при помощи свойства z-index. Чем выше значение этого свойства, тем ближе к переднему плану выводится элемент. Элементы с более низкими значениями z-index выводятся на заднем плане.

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

[customscript]techrocks_custom_after_post_html[/customscript]

[customscript]techrocks_custom_script[/customscript]

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх