Поток документа и позиционирование
Free PreviewКогда мы говорили о блочных и строчных элементах мы затрагивали такое понятие как поток документа. Давайте обсудим подробнее что это такое и чем может быть полезно изменение потока документа.
Поток документа
Поток документа — это порядок, в котором браузер размещает элементы на странице. Давайте еще раз отметим ключевые моменты стандартного потока:
- Элементы идут сверху вниз;
- Блочные (
<div>,<p>,<section>) — занимают всю ширину, каждый с новой строки; - Строчные (
<span>,<a>,<strong>) — идут внутри строки; - Отступы (
margin,padding) влияют на соседей.
Стардатным потоком называется порядок элементов по умолчанию. То что элементы располагаются в таком порядке определяется CSS свойством position. Его значение по умолчанию - static.
По умолчанию, если мы не трогаем свойство position все элементы страницы живут в стандартном потоке. Каждый элемент занимает определенное место и влияет на расположение других элементов. Но существуют и другие возможные значения этого свойства, которые позволяют переопределить стандартное поведение.
Position: relative
Иногда в процессе вёрстки требуется реализовать разные сложные идеи дизайнера про расположение элементов друг относительно друга. Например, расположить один элемент поверх другого или немного сместить отображение элемента относительно своего начального положения.
Одним из способов изменить положение элемента в потоке является свойство position: relative. Оно позволяет сместить элемент относительно начального положения на страницы. При этом важно помнить несколько основных моментов:
- Сам по себе
position: relativeвизуально ничего не меняет, чтобы элемент сместился нам нужно дополнительно задать смещение с помощью свойств top, bottom, left, right. Каждое из них задает смещение в соответсвующую сторону. Можно смещать элемент отдельно по какой-то оси или сразу в нескольких направлениях, например вправо и вниз или влево и вверх и т.д. - При применении
position: relativeвнутри элемента резервируется место под элемент, как если бы он был в стандартном потоке, другие элементы страницы не меняют своего положения (кроме случая, когда элемент выходит за границы родителя).
Рассмотрим следующий пример кода:
<div class="box1">Блок 1</div> <div class="box2">Блок 2</div> <style> div { width: 200px; padding: 10px; border: 1px solid black; margin: 10px; } .box1 { background-color: blue; } .box2 { position: relative; bottom: 30px; left: 30px; background-color: aqua; } </style>html
В результате получается следующая картинка:

Элемент со свойством position: relative смещен относительно исходного положения вправо и вверх. Свойство bottom задает смещение элемента по вертикали, т.е. мы указываем сколько пикселей должно быть между нижним краем элемента в исходном положении и нижним краем после смещения. Соответсвенно свойство right создает отступ с правого края.
Исходное точкой отсчета для вычисления новой позиции элемента является нижний левый угол элемента/
Position: absolute
Другим часто используемым значением свойства position является absolute. У такого позиционирования есть ряд своих особенностей:
- В случае абсолютного позиционирования элемент убирается из основного потока документа и перестает влиять на другие элементы страницы. Можно представить себе, что элемент уходит на слой выше и перестаёт взаимодействовать со всеми элементами, кроме своих потомков.
- Элемент позиционируется относительно ближайшего позиционированного предка. Если все предки имеют
position: staticто элемент будет спозиционирован относительно всего документа. - Если
position: absoluteприменить к строчному элементу он станет вести себя как блочный. Ширина блочных элементов сposition: absoluteопеределяется шириной контента.
Рассмотрим следующий пример:
<div class="box1">Блок 1</div> <div class="box2">Блок 2</div> <div class="box3">Блок 3</div> <style> div { width: 200px; padding: 10px; border: 1px solid black; margin: 10px; } .box1 { background-color: blue; } .box2 { position: absolute; top: 30px; left: 30px; background-color: aqua; } .box3 { background-color: gray; }html
Результат этого кода на картинке ниже:

Обратите внимание, в основном потоке документа не резервируется место для блока с номером 2. Из-за того что у блоков нет родителя с измененным позиционированием то смещение отсчитывается от окна страницы, top и left задают отступы от верхнего и левого края соответсвенно.
Здесь стоит остановиться на моменте, который не всегда бывает очевидным для новичков.
Относительно чего позиционируется position: absolute
Как мы уже сказали, элемент с position: absolute позиционируется относительно ближайшего позиционированного предка.
Под позиционированным понимается элемент, у которого значение свойства position отлично от static (relative, absolute, fixed, sticky).
Если такого предка нет, браузер берёт в качестве точки отсчёта всё окно документа (viewport).
Рассмотрим это на примерах.
Пример 1. Родитель без позиционирования
Для первого примера используем следующий код:
<div class="parent"> Родитель <div class="child">Дочерний элемент</div> </div> <style> .parent { width: 200px; height: 100px; border: 2px solid black; margin: 50px; } .child { position: absolute; top: 20px; left: 20px; background-color: aqua; padding: 10px; } </style>html
Результатом этого кода будет следующая картинка:

Визуально дочерний элемент вылез за пределы родителя. Это происходит из-за того, что блок-родитель имеет позионирование по умолчанию и координаты для смещения дочернего блока расчитываются от окна документа.
Пример 2. Родитель с position: relative
Теперь изменим всего одну строку в коде из примера 1. Добавим свойство position: relative к родительскому блоку:
.parent { position: relative ... }css
После добавления этой строки родительский блок становится позиционированным элементом и положение дочернего блока будет отсчитываться относительно родителя, а не окна документа:

Благодаря тому, что мы не добавляли свойств для смещения родителя он остался в стандартном потоке. Таким образом position: relative часто используют не для смещения элемента, а чтобы сделать его контейнером для absolute.
Position: fixed
Иногда требуется позиционировать элемент не относительно родителя, а относительно окна браузера вне зависимости от вложенности. Для решения подобной задачи подходит position: fixed. Свойство так же, как и предыдущее, работает с указанием смещения.
При position: fixed элемент также убирается из основного потока документа. Практически во всех случаях расчет положения элемента производится относительно окна браузера, за исключением случаев, если один из родителей имеет установленные значения CSS свойств transform, perspective или filter.
position: fixed идеально подходит для создания элементов, которые будут постоянно видимы пользователю - всевозможные меню, кнопка "наверх" для прокрутки страницы к началу и т.д. Попробуйте самостоятельно поэкспериментировать с такими элементами.
Position: sticky
Еще одним возможным значением свойства position я вляется sticky, в переводе с английского - "липкий". Собственно так себя и ведет элемент с таким свойством:
- До тех пор, пока его родитель не будет прокручен до определённой границы, элемент ведёт себя как элемент с относительным (
relative) позиционированием. - Элемент остаётся «приклеенным» во время прокрутки родителя до тех пор, пока не «встретит» противоположную границу своего родителя. Пока элемент "приклеен" он ведет себя как будто у него установлено
position: fixed.
Основное правило при работе с position: sticky состоит в том, что для его корректной работы необходимо указать хотя бы одно из свойств top, bottom, left, right.
position: sticky особенно полезен для создания всевозможных заголовки таблиц, меню разделов, навигации внутри длинных страниц и т.д.