Flow is one of the most important basic concepts in layout. It is the principle of organizing elements on the page in the absence of styles: if we write HTML and do not write CSS, the display in the browser will be predictable because we absolutely know how the browser arranges elements in the flow.
Even if no styles are linked to the page, CSS rules that are "built-in" to the browser engine will still be applied to each element. Because of these rules, the header <h1>
is larger than the header <h2>
, and links are blue and underlined. Based on these rules, conditionally all elements on the page can be divided into two categories: block (block) and inline (inline). For example, <div>
will be block, while <span>
or <a>
will be inline. The standard behavior can be changed using the CSS property display
.
If no styles are applied at all, the browser forms a normal flow from elements. The behavior of block elements in a normal flow differs from the behavior of inline elements.
Formatting Context
The rules for positioning inline and block elements in a normal flow are called formatting context. Block elements participate in forming a block formatting context. Inline elements form an inline formatting context. The positioning of elements in the formatting context depends on the writing direction for the specific language. For example, texts in European languages are read and written left to right, top to bottom. This means that by default, the formatting context arranges block elements from top to bottom and inline elements from left to right. However, in the case of East Asian languages such as Chinese, Japanese, and Korean, when vertical writing is used, we see a completely different picture: block elements will be arranged from right to left, and inline elements from top to bottom.
In all examples below, the writing direction characteristic of European languages will be considered: words from left to right, blocks from top to bottom. But all the same explanations can apply to other writing directions.
Block Elements in Normal Flow
Block elements in normal flow are arranged one below the other, always taking the entire width of the parent. The height of a block element by default equals the height of its content. Three paragraphs in HTML will be positioned in exactly the same order on the page.
Even if the width of a block element is explicitly set and allows another such element to fit on the right, the flow will still continue to stack them one below the other.
One can think of a block element as a float that strives to rise higher on the page. And it continues to rise until it meets another element or the boundary of the parent.
Inline Elements in Normal Flow
Inline elements are arranged one after another, like words in a sentence. Depending on the writing direction in a specific language, elements can be arranged from left to right (for example, in Russian), from right to left (as in Hebrew), and even from top to bottom (like characters and syllabic signs in Japanese vertical writing). The width and height of an inline element equals the width and height of its content. Unlike block elements, we cannot control the width and height of an inline element through CSS. Several inline elements will try to fit on one line as much as the width of the parent allows. If the width of the parent is insufficient, the excess text of the inline element will wrap to the next line.
Collapsing and Dropping Margins
In a block formatting context, the vertical distances between the blocks are set by the CSS property margin
. If the block has a lower margin set and the next block has an upper margin set, one might expect that the total margin between the blocks will equal the sum of these two margins. However, according to the specification, touching margins "collapse." That is, they seem to sink into one another. The total margin will equal the greater of the two margins.
If the first child element in a block has a top margin or the last element has a bottom margin, those margins "drop" into the outside world from their parent.
Dropping margins from the parent can be prevented in several ways, for example:
- Set the parent a vertical inner margin
padding
or- top padding
depending on which side we want to prevent from dropping.- bottom - Set the parent a top or bottom border with the same logic. The border can be transparent; the main thing is that it exists :)
- Set the parent the
overflow
property to a value different fromvisible
. - Override the parent's
display
property toflow
, or to- root flex
orgrid
(but in the latter case, its descendants will not be laid out according to normal flow rules but according to flexbox and grid layout rules respectively).
Flow Out of the Document
Earlier we found out that all elements are by default in normal flow. But this behavior can be changed using certain CSS properties. When these properties are changed, an element stops interacting with other blocks in the flow. It is said that it has "flowed out of the document."
It should be noted that elements that have flowed out of the document create a sort of mini-flow within themselves. Their child elements will obey the interaction rules in the flow within the parent.
Floating using float
When we make an element float, it stops interacting with other elements in the block context. However, it continues to interact with the inline context. Text elements flow around this block on one side.
Positioning an Element Using position
If an element is given absolute or fixed positioning, it also leads to flowing out of the document. But in this case, our element does not participate even in the inline context.
With absolute or fixed positioning, the element seems to rise above the content of the page and becomes "invisible" to all other blocks.