Поток — одно из важнейших базовых понятий в вёрстке. Это принцип организации элементов на странице при отсутствии стилей: если мы напишем HTML и не напишем CSS, то отображение в браузере будет предсказуемо благодаря тому, что мы абсолютно точно знаем, как браузер располагает элементы в потоке.
Даже если к странице не подключено никаких стилей, к каждому элементу всё равно будут применяться CSS-правила, «зашитые» в движке браузера. Благодаря этим правилам заголовок <h1>
крупнее заголовка <h2>
, а ссылки — синие и подчёркнутые. На основании этих правил условно все элементы на странице можно разделить на две категории: блочные (block) и строчные (inline). Например, <div>
будет блочным, а <span>
или <a>
— строчным. Поменять стандартное поведение можно при помощи CSS-свойства display
.
Если вообще не применять никаких стилей, браузер формирует из элементов нормальный поток. Поведение блочных элементов в нормальном потоке отличается от поведения строчных.
Контекст форматирования
СкопированоПравила расположения строчных и блочных элементов в нормальном потоке называются контекстом форматирования. Блочные элементы участвуют в формировании блочного контекста форматирования. Строчные элементы формируют строчный контекст форматирования. Расположение элементов в контексте форматирования зависит от направления письма для конкретного языка. Например, тексты на европейских языках мы читаем и пишем слева направо сверху вниз. Это означает, что по умолчанию контекст форматирования располагает блочные элементы сверху вниз, а строчные — слева направо. Но, например, в случае с восточноазиатскими языками, такими как китайский, японский и корейский, когда используется вертикальное письмо, мы видим совершенно другую картину: блочные элементы будут располагаться справа налево, а строчные — сверху вниз.
Во всех примерах далее будет рассматриваться направление письма, характерное для европейских языков: слова — слева направо, блоки — сверху вниз. Но все те же объяснения можно применять и для другого направления письма.
Блочные элементы в нормальном потоке
СкопированоБлочные элементы в нормальном потоке располагаются друг под другом, всегда занимая всю доступную ширину родителя. Высота блочного элемента по умолчанию равна высоте его содержимого. Три абзаца, идущие друг за другом в HTML, будут располагаться точно в таком же порядке и на странице.
Даже если ширина блочного элемента явно задана и позволяет разместить справа ещё один такой элемент, поток всё равно продолжит выстраивать их друг под другом.
Можно воспринимать блочный элемент как поплавок, который стремится всплыть на странице как можно выше. И всплывает до тех пор, пока не встретит на пути другой элемент или границу родителя.
Строчные элементы в нормальном потоке
СкопированоСтрочные элементы располагаются друг за другом, как слова в предложении. В зависимости от направления письма в конкретном языке элементы могут располагаться слева направо (например, в русском языке), справа налево (как, например, в иврите) и даже сверху вниз (как иероглифы и знаки слоговых азбук в японском вертикальном письме). Ширина и высота строчного элемента равна ширине и высоте содержимого. В отличие от блочного элемента, мы не можем управлять шириной и высотой строчного элемента через CSS. Несколько строчных элементов будут стремиться уместиться на одной строке, насколько хватает ширины родителя. Если ширины родителя не хватает, то лишний текст строчного элемента переносится на следующую строку.
Схлопывание и выпадение отступов
СкопированоВ рамках блочного контекста форматирования вертикальные расстояния между блоками задаются CSS-свойством margin
. Если блоку задан нижний отступ, а следующему за ним — верхний, то можно ожидать, что итоговый отступ между блоками будет равен сумме этих двух отступов. Но в соответствии со спецификацией соприкасающиеся отступы «схлопываются». То есть как бы проваливаются один в другой. Итоговый отступ будет равен бо́льшему отступу из двух.
Если первому дочернему элементу в блоке задан верхний отступ или последнему элементу — нижний, то эти отступы «выпадают» во внешний мир из своего родителя.
Выпадение отступов из родителя можно предотвратить несколькими способами, например:
- Задать родителю вертикальный внутренний отступ
padding
или- top padding
в зависимости от того, с какой стороны мы хотим предотвратить выпадение.- bottom - Задать родителю верхнюю или нижнюю рамку по такой же логике. Рамка может быть прозрачной, главное, чтобы она была :)
- Задать родителю свойство
overflow
со значением, отличным отvisible
. - Переопределить родителю свойство
display
наflow
, либо на- root flex
илиgrid
(но в последнем случае его потомки будут раскладываться уже не по правилам нормального потока, а по правилам флексбоксов и грид-раскладки соответственно).
Выход из потока
СкопированоРанее мы выяснили, что все элементы по умолчанию находятся в нормальном потоке. Но это поведение можно поменять при помощи некоторых CSS-свойств. При изменении значений этих свойств элемент перестаёт взаимодействовать с остальными блоками в потоке. Говорят, что он «вышел из потока».
Тут нужно отметить, что элементы, вышедшие из потока, создают внутри себя своего рода мини-поток. Их дочерние элементы будут подчиняться правилам взаимодействия в потоке в пределах родителя.
Обтекание при помощи float
СкопированоКогда мы делаем элемент плавающим, он перестаёт взаимодействовать с другими элементами блочного контекста. При этом со строчным контекстом наш плавающий блок продолжает взаимодействовать. Текстовые элементы обтекают такой блок с одной из сторон.
Позиционирование элемента при помощи position
СкопированоЕсли задать элементу абсолютное или фиксированное позиционирование, это также приводит к выходу из потока. Но только в этом случае наш элемент не участвует даже в строчном контексте.
При абсолютном или фиксированном позиционировании элемент как бы поднимается над содержимым страницы, и становится «не виден» всем остальным блокам.