skip to main content

Поток документа

html

Поток — одно из важнейших базовых понятий в вёрстке. Это принцип организации элементов на странице при отсутствии стилей. Если мы просто напишем HTML из нескольких тегов и не напишем CSS, то отображение в браузере будет предсказуемо благодаря тому, что мы абсолютно точно знаем, как браузер располагает элементы в потоке.

Даже если к странице не подключено никаких стилей, к каждому элементу всё равно будут применяться CSS-правила, «зашитые» в движке браузера. Благодаря этим правилам мы видим заголовок <h1> крупнее заголовка <h2>, а ссылки — синими и подчёркнутыми. На основании этих правил условно все элементы на странице можно разделить на две категории: блочные (block) и строчные (inline). Например, <div> будет блочным, а <span> или <a> — строчным. Поменять стандартное поведение можно при помощи CSS-свойства display.

Если вообще не применять никаких стилей, браузер формирует из элементов нормальный поток. Поведение блочных элементов в нормальном потоке отличается от поведения строчных.

Контекст форматирования 🔗

Правила расположения строчных и блочных элементов в нормальном потоке называются контекстом форматирования. Блочные элементы участвуют в формировании блочного контекста форматирования. Строчные элементы формируют строчный контекст форматирования. Расположение элементов в контексте форматирования зависит от направления письма для конкретного языка. Например, тексты на европейских языках мы читаем и пишем слева направо сверху вниз. Это означает, что по умолчанию контекст форматирования располагает блочные элементы сверху вниз, а строчные — слева направо. Но если рассмотреть японский язык, мы видим совершенно другую картину: блочные элементы будут располагаться слева направо, а строчные — сверху вниз.

Во всех примерах далее будет рассматриваться направление письма, характерное для европейских языков: слова — слева направо, блоки — сверху вниз. Но все те же объяснения можно применять и для другого направления письма.

Блочные элементы в нормальном потоке 🔗

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

See the Pen normal flow 1 by Denis Ezhkov (@ezhkov) on CodePen.

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

See the Pen normal flow 2 by Denis Ezhkov (@ezhkov) on CodePen.

Можно воспринимать блочный элемент как поплавок, который стремится всплыть на странице как можно выше. И всплывает до тех пор, пока не встретит на пути другой элемент или границу родителя.

See the Pen normal flow 1 animated by Denis Ezhkov (@ezhkov) on CodePen.

Строчные элементы в нормальном потоке 🔗

Строчные элементы располагаются друг за другом, как слова в предложении. В зависимости от направления письма в конкретном языке элементы могут располагаться слева направо (например, в русском языке), справа налево (как, например, в иврите) и даже сверху вниз, как иероглифы в японском письме. Ширина и высота строчного элемента равна ширине и высоте содержимого. В отличие от блочного элемента, мы не можем управлять шириной и высотой строчного элемента через CSS. Несколько строчных элементов будут стремиться находиться на одной строке, пока их все можно уместить в ширину родителя. Если ширины родителя не хватает, то лишний текст строчного элемента переносится на следующую строку.

See the Pen normal flow 3 by Denis Ezhkov (@ezhkov) on CodePen.

Схлопывание и выпадение отступов 🔗

В рамках блочного контекста форматирования вертикальные расстояния между блоками задаются CSS-свойством margin. Если блоку задан нижний отступ, а следующему за ним — верхний, то можно ожидать, что итоговый отступ между блоками будет равен сумме этих двух отступов. Но в соответствии со спецификацией соприкасающиеся отступы «схлопываются». То есть, как бы проваливаются один в другой. Итоговый отступ будет равен бóльшему отступу из двух.

See the Pen normal flow 4 by Denis Ezhkov (@ezhkov) on CodePen.

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

See the Pen normal flow 5 by Denis Ezhkov (@ezhkov) on CodePen.

Выпадение отступов из родителя можно предотвратить несколькими способами:

  • задать родителю вертикальный внутренний отступ padding-top или padding-bottom в зависимости от того, с какой стороны мы хотим предотвратить выпадение;
  • задать родителю верхнюю или нижнюю рамку по такой же логике. Рамка может быть прозрачной, главное, чтобы она была :);
  • задать родителю свойство overflow, отличное от none;
  • переопределить родителю свойство display на flex или grid.

Выход из потока 🔗

Ранее мы выяснили, что все элементы по умолчанию находятся в нормальном потоке. Но это поведение можно поменять при помощи некоторых CSS-свойств. При изменении значений этих свойств элемент перестаёт взаимодействовать с остальными блоками в потоке. Говорят, что он «вышел из потока».

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

Задание свойства float 🔗

Когда мы делаем элемент плавающим, он перестаёт взаимодействовать с другими элементами блочного контекста. При этом со строчным контекстом наш плавающий блок продолжает взаимодействовать. Текстовые элементы обтекают такой блок с одной из сторон.

See the Pen normal flow 6 by Denis Ezhkov (@ezhkov) on CodePen.

Позиционирование элемента при помощи position 🔗

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

See the Pen normal flow 7 by Denis Ezhkov (@ezhkov) on CodePen.

При абсолютном или фиксированном позиционировании элемент как бы поднимается над содержимым страницы, и становится «не виден» всем остальным блокам.

Автор: Денис,