Вы здесь: Главная » CSS » Позиционирование элементов

Позиционирование элементов

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

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

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

Также для всех позиций, кроме static, можно задать свойство z-index, которое определяется цифрой (0, -1, 10, 999) без указания единиц, т.к. это свойство показывает, на каком уровне (или слое) находится спозиционированный элемент по сравнению с другими позиционированными элементами (выше или ниже). Чем меньше цифра, тем ниже будет находится элемент среди себе подобных (т.е. тех элементов, у которых свойство position  имеет значение relative, absolute, fixed или sticky.  Для элементов с position: static свойства z-index или любая из координат (left, right, top, bottom) будут проигнорированы.

Элементы с position: relative

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

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

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

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

Элементы с position: absolute

При абсолютном позиционировании элемента без указания координат он будет привязан своим левым краем к левому краю родительского контейнера, но его ширина изменится: если текста мало - уменьшится, если текста (контента) много, то ширина блока увеличится, и он "вылезет" за пределы контейнера справа.

Как только этому элементу будут заданы координаты, он "сбежит" из родительского контейнера и разместится относительно body, заняв при этом все доступное пространство внутри body, если имеет приличное количество контента. Если контента мало (1-2 слова, например), то блок "примостится" сверху статического контента, не оставив и следа там, где был в первоначальной разметке.

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

В примере ниже вы можете посмотреть, как изменяется положение и вид блока, которому назначили свойство position: absolute. Для этого вам нужно будет нажать на соответствующую кнопку внизу примера. Обратите внимание, что элемент уменьшил свою ширину. Высота осталась примерно такой же за счет добавления кнопки вместо второго параграфа. Учтите, что первоначально для элемента с position: absolute ни одна координата не задана. Они добавятся только после того, как вы начнете перемещать ползунки. Кроме того, для абсолютно позиционированного элемента можно назначить все 4 координаты (left, top, right, bottom).  Если их значения не будут противоречить друг другу, элемент ... растянется. Нажмите на кнопку "Все координаты в 0" и посмотрите на ширину элемента. Она займет все доступное пространство внутри body или элемента-родителя. Кстати, кнопка "Вернуть в пределы родительского элемента" позволит вам посмотреть на разницу в расчете координат. В самом блоке есть кнопка "Убрать координаты", которая поможет в случае слишком большой растяжки элемента с  position: absolute.

Вы можете поэкспериментировать с примером, рассматривающим абсолютное позиционирование, в отдельной вкладке. Красной двойной рамкой в этом примере выделены размеры body, синей точечной - пределы родительского элемента.

Элементы с position: fixed

Это фиксированные элементы, которые без указания координат "прилипают" к левому краю родительского блока и не смещаются при прокрутке страницы. Как только координаты заданы, элемент "открепляется" от родителя и позиционируется относительно body. Опять-таки он не смещается при прокрутке страницы, т.к. зафиксирован в определенных координатах.

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

fixed+ parent relative

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


В этом примере красная рамка ограничивает размеры body, синяя - размеры родительского элемента.

Протестируйте пример с фиксированным позиционированием элемента в отдельной вкладке.

Обратите внимание, что при назначении отрицательных координат элементы с position: absolute и fixed уходят под рамки браузера (элемента), поэтому их часто используют для создания выезжающих меню, форм, баннеров и кнопок для прокрутки вверх, которые прячутся, когда не нужны.

Элементы с position: sticky

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

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

В примере ниже вам необходимо прокрутить файл, разбитый на несколько секций, чтобы увидеть, как  каждый заголовок типа "Section 1" "прилипает" к верхнему краю из-за назначенного ему свойства top: 0. После того, как его сменяет Section 2, "прилипает" уже этот заголовок.

Код для заголовков здесь таков:

Фоновый цвет для заголовка нужен, чтобы его текст лучше читался. В примере он белый и совпадает с цветом фона страницы. Также имеет смысл убрать прозрачные внешние отступы (margin: 0) и вместо них добавить внутренние (padding: 10px 0), чтобы фоновый цвет занимал больше пространства.

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

Использование свойства z-index

До этого момента мы не рассматривали порядок наложения позиционированных элементов друг на друга, т.к. у нас был только один такой элемент в тестовых файлах. Тем не менее ситуация, когда в пределах одного блока может быть несколько относительно, абсолютно или фиксированно спозиционированных элементов, часто встречается на практике.  Тогда следует использовать свойство z-index, позволяющее определять порядок наложения спозиционированных блоков друг на друга. Поскольку раскладка элементов определяется в основном в двумерном пространстве, т.е.  по осям X и Y, то определение наложения происходит по оси Z, перпендикулярной плоскости экрана. Каждый их таких элементов может находиться как ниже, так и выше других объектов веб-страницы при заданном свойстве z-index. Рассмотрим его подробнее.

z-axis

Свойство z-index задается цифрой. Это может быть 0, положительное или отрицательное значение. По умолчанию у каждого позиционированного элемента (position: relative | absolute | fixed) свойство z-index имеет значение auto. В этом случае каждый следующий в разметке элемент с заданным свойством position из перечисленных значений накладывается на предыдущий. При явном указании z-index в виде числа элемент перемещается выше или ниже соседних элементов.

В примере ниже представлены карты, для которых задано абсолютное позиционирование и координаты left и top таким образом, чтобы они накладывались друг на друга. Разметка и css-свойства этого примера таковы:

По умолчанию все карты имеют z-index: auto и накладываются в порядке размещения в html-коде. Вы можете щелкнуть по любой карте (она приобретет красную обводку) и изменять свойство z-index с помощью ползунка или цифр в специальном поле.

Обратите внимание на то, что отрицательный z-index закрывает доступ к элементу - вы уже не можете выделить его, чтобы назначить другое значение. Если бы внутри этого элемента были ссылки, вы бы не смогли щелкнуть по ним. Поэтому использовать отрицательные значения z-index нужно с осторожностью. Воспользуйтесь кликом на тексте "значение auto для всех карт", чтобы вернуть начальное состояние элементам.

Контекст наложения (stacking context)

Использование z-index вроде бы не предпоагает никаких сложностей. Обычно их и не бывает. Однако в спецификации есть один нюанс, связанный с термином контекст наложения (stacking context). Это концепция трехмерного расположения html-элементов вдоль оси Z, перпендикулярной к пользователю, находящемуся перед экраном. Обычно эти элементы занимают место по порядку друг за другом, но есть ряд свойств, который меняет позицию элемента по оси Z.

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

  • является корневым элементом (html),
  • позиционирован абсолютно (position:absolute) или относительно (position:relative) с z-index значением отличным от "auto", или имеет position: fixed
  • flex-элемент с z-index отличным от  "auto", чей родительский элемент имеет свойство display: flex|inline-flex,
  • элементы с  opacity меньше чем 1. (См. the specification for opacity),
  • элементы с  transform отличным от "none",
  • элементы с mix-blend-mode значением отличным от "normal",
  • элементы с filter значением отличным от "none",
  • элементы с isolation установленным в  "isolate",
  • если мы указываем элементу атрибут  will-change при этом не обязательно присваивать ему значения (См. эту статью)
  • элементы с -webkit-overflow-scrolling установленым в "touch"

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

В примере ниже у нас есть несколько элементов с относительным (position: relative) или абсолютным (position: absolute) позиционированием. Разметка этого примера такова:

Каждому div-у в этой разметке задан z-index. Тестовым элементом у нас является div#2, для которого изначально z-index НЕ задан, т.е. он имеет значение auto по умолчанию. Желтый div#4 с z-index:6, который размещен внутри  div#2 как дочерний элемент, сейчас накладывается на зеленый div#1 с z-index:5, т.к. его цифра 6 предполагает более высокое расположение позиционированного элемента по оси Z по сравнению с цифрой 5. Однако стоит задать div#2 свойство z-index: 1 или 2 - и его вложенные элементы спрячутся под зеленые блоки, т.к. контекст наложения сейчас учитывает z-index только родительского элемента в ряду с его соседними - это div#1 и div#3.

Второй способ изменить контекст наложения div#2 - это задать этому div-у свойство opacity < 1 при стандартном значении свойства z-index: auto.  В нашем приме opacity уменьшается до значения 0.7, чтобы это было четко видно, хотя достаточно назначить и 0.99, которое визуально почти не отличается от 1.

Все остальные значения z-index для div#2 поднимают его выше или опускают ниже зеленых блоков, но все вложенные в него элементы определяют свое расположение по оси Z относительно друг друга, но не относительно соседних элементов родителя.

Ссылка по теме на developer.mozilla.org

Добавить комментарий

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