#Normal flow
AddedNormal flow is the layout every element gets until you say otherwise. Block-level boxes (div, p, section, headings) are laid out one after another in the block direction — top to bottom in English — and each one stretches to fill the width of its container. Inline-level boxes (span, a, strong, text, inline-block elements) are laid out side by side in the inline direction, left to right, inside line boxes, and wrap onto a new line when they run out of room.
A good mental model is a word processor. Paragraphs stack down the page, each as wide as the page; inside a paragraph, words flow along a line and wrap. Everything takes up room, and everything pushes the next thing along. Taking an element out of flow — with position: absolute or fixed, or with float — is like peeling a sticky note off the page: it's still visible, but the text closes up behind it as if it were never there.
Normal flow is also what the other layout modes are measured against. Flexbox and grid don't remove anything from flow; they replace the flow of their children with a different algorithm (see The flex model). The position values in this chapter all start from where a box would sit in normal flow and then decide how far to move it, or whether it still takes up space.
.page { width: 300px; padding: 10px; background: #f1f5f9; }
.block { height: 40px; margin-bottom: 10px; background: #dbeafe; color: #1e3a8a; }
.line { line-height: 30px; }
.chip {
display: inline-block; vertical-align: top;
width: 80px; height: 30px;
background: #fde68a; text-align: center;
}<div class="page">
<div class="block" id="b1">Block 1</div>
<div class="block" id="b2">Block 2</div>
<div class="line"><span class="chip" id="c1">A</span><span class="chip" id="c2">B</span><span class="chip" id="c3">C</span><span class="chip" id="c4">D</span></div>
</div>.pageis 300px wide with 10px padding. Its children are laid out inside the 300px content box, starting 10px in from its edges.#b1and#b2are blocks withwidth: auto, so each one fills the available width: both measure exactly 300px. You never told them how wide to be; filling the container is whatautomeans for a block in normal flow.- The blocks stack in the block direction:
#b2starts 10px below#b1, because of#b1'smargin-bottom: 10px. Each block pushes the next one down by its full height plus margins. - Inside
.line, the four chips areinline-block: they sit on a line side by side. A, B and C touch (B.left − A.right = 0, since there is no whitespace between them in the markup), using 240 of the 300px. - D would need 80px more (320px in total), so it wraps: it starts a new line box 30px lower (the line height), back at the left edge of the content box.
- Everything in flow adds to the parent's height:
.pageis10 + 40 + 10 + 40 + 10 + 30 + 30 + 10 = 180px. That's the property that makes normal flow so robust: change any child's size and everything after it moves to make room.
"Block direction" and "inline direction" are used on purpose. They follow the writing mode, and in a vertical writing mode blocks stack sideways. This is why modern CSS has logical properties such as margin-block-end and inline-size (see Logical properties).
.vertical { writing-mode: vertical-rl; height: 160px; background: #f1f5f9; }
.vblock { block-size: 40px; margin-block-end: 10px; background: #dbeafe; color: #1e3a8a; }<div class="vertical">
<div class="vblock" id="v1">Block 1</div>
<div class="vblock" id="v2">Block 2</div>
</div>writing-mode: vertical-rlturns the inline direction to top-to-bottom and the block direction to right-to-left.- So the first block sits against the right edge, and the second one stacks to its left, 10px away (
margin-block-endis now a left margin). - Each block fills the inline size of the container, which is now its height: both are 160px tall.
block-size: 40pxbecame their width. - Same algorithm, rotated. Normal flow is defined in terms of block and inline directions, not "down" and "across".
.wrap { width: 300px; background: #f1f5f9; }
.out { position: absolute; width: 100px; height: 100px; }
.side { float: left; width: 80px; height: 120px; }
.in { height: 60px; }<div class="wrap">
<div class="out"></div>
<div class="side"></div>
<div class="in"></div>
</div>Show answer
60px. Only .in is in normal flow. The absolutely positioned box and the float are both out of flow, so they don't add to the wrapper's height, even though they stick out below it.
.wrap { width: 300px; background: #f1f5f9; margin-bottom: 70px; }
.out { position: absolute; width: 100px; height: 100px; background: #fca5a5; }
.side { float: left; width: 80px; height: 120px; background: #bbf7d0; }
.in { height: 60px; background: #dbeafe; }<div class="wrap">
<div class="out">out</div>
<div class="side">side</div>
<div class="in">in</div>
</div>.outisposition: absolutewith no offsets, so it stays at its static position (where it would have been: the top-left of.wrap) but takes up no space..sideis a float. Floats are out of flow for their parent's height too, so it hangs 60px below the wrapper..inis the only in-flow child. Its block box starts at the very top of.wrap(block boxes run under floats; only line boxes move aside, see Floats and clearing), and its 60px is the wrapper's whole height.- Painting order decides who's visible where they overlap: the positioned
.outpaints above the float, and the float paints above the in-flow block's background.elementFromPointfinds.outat the corner,.sidejust below it, and.into the right. - To make the wrapper contain the float, give it
display: flow-root. Nothing makes it grow for an absolutely positioned child: that's the point of absolute positioning.