CSS Display and Normal Flow: Block, Inline, Inline-Block
Normal flow is the browser's default way of arranging boxes before another layout rule changes them. A document with headings and paragraphs remains readable without custom CSS because block content follows the document order and inline content wraps inside each line. For the broader styling basics, start with the guide to CSS. This guide is part of our CSS layout guide series.
Think of the layout as a printed page. A paragraph begins as a new block, words run inline across its lines, and a small label can sit inside a line while keeping its own rectangular size. The display property tells the browser which of those page roles a box should use.
What Is Normal Flow in CSS?
Normal flow lays out block boxes in document order and inline content within lines. The display property can change how a box sits among its siblings and how its children are arranged. Those are its outer and inner display types.
display: block;
display: inline;
display: inline-block; The browser’s default stylesheet supplies useful display values for common HTML elements. Paragraphs, headings, lists, and div elements normally generate block boxes. Links, span elements, strong, and em normally generate inline boxes. CSS can change the display type without changing the element's semantic meaning.
Normal flow also preserves the document's source order. A later block follows the earlier block, and text wraps when the available inline space runs out. Flexbox, grid, floats, and positioning modify parts of that arrangement, so debugging starts by identifying what normal flow would have done.
How Do CSS Block, Inline, and Inline-block Differ?
In CSS normal flow, a block box starts a new line, an inline text box shares the surrounding line, and an inline-block shares the line while accepting a width and height. Try each display value on a notice, highlighted phrase, or tag to see how much space it takes.
Block Starts a New Line
.notice {
display: block;
width: 18rem;
padding: 1rem;
margin-block: 1rem;
} The notice begins on a new line. Its declared width is respected, and the vertical padding plus margins create space around the full rectangle. Without the explicit width, the block's outer box normally expands across the available width of its containing block.
Inline Stays with the Text
.highlight {
display: inline;
width: 10rem;
padding-inline: 0.25rem;
background: #dcebe5;
} The highlighted words remain inside the sentence and can wrap across lines. Horizontal padding moves neighboring text away from the painted background. The browser ignores the ordinary width: 10rem because a non-replaced inline box (an inline box containing text rather than embedded content such as an image) takes its width from the text fragments inside the line.
Inline-block Stays Inline and Accepts a Size
.tag {
display: inline-block;
width: 6rem;
padding: 0.35rem 0.5rem;
text-align: center;
} The tag sits beside surrounding text like another inline item, while its contents use a block-style rectangle. The browser now respects the width and vertical padding. This combination suits a compact badge or label that belongs in a text line but needs predictable dimensions.
The printed-page model still holds for all three. Block begins a new region, inline joins the words already running across the line, and inline-block places a measured label within that same line. Choose the role from the space the element should claim.
Common Pitfalls & Debugging
Width Has No Effect on an Inline Box
A width or height declaration appears in developer tools but the element does not change size. The element is a non-replaced inline box. Use inline-block when the element should stay in the text line, or block when it should start a new line.
Vertical Margins Collapse
Two stacked blocks with vertical margins produce less space than adding both values suggests. Adjoining vertical margins in block flow can collapse into one margin, usually using the larger positive value. Set the intended spacing on one side, or create a new formatting context when the container's layout requires separate margins.
.section {
display: flow-root;
}
.section > * {
margin-block: 0;
}
.section > * + * {
margin-block-start: 1rem;
} flow-root creates a new block formatting context, which stops the section's margins from collapsing with child margins through the container edge. Adjacent child margins can still collapse with each other. Resetting those margins lets the adjacent-sibling rule own the spacing in one predictable place.
Inline Padding Overlaps Nearby Lines
An inline highlight's background or border paints over text in the line above or below. Vertical padding paints around the inline box without increasing the line box spacing in the same way a block dimension would. Use inline-block for a self-contained label, or adjust the surrounding line height when the effect belongs to ordinary text.
Choose the Display Value That Fits
Normal flow gives every box a useful starting place. Use block for a new region, inline for text fragments, and inline-block for a measured box that must remain inside the line.
Frequently Asked Questions
What is normal flow in CSS?
Normal flow is the browser's default system for arranging boxes before floats, positioning, flexbox, or grid change their layout. Block boxes follow one another in the block direction, while inline boxes flow together inside line boxes.
What is the difference between CSS block, inline, and inline-block?
A CSS block box starts on a new line and normally fills the available width. A non-replaced inline box, such as a text span, stays in the text line and ignores width and height. An inline-block box stays in the line but accepts dimensions. Inline images are an exception because their dimensions can be set.
Do margins collapse in flexbox or grid?
Margins between CSS flex items or grid items do not collapse. Margin collapsing applies to adjoining margins in block flow. Use gap when you want consistent spacing between flex or grid items.
Does display: none remove an element from flow the same way position: absolute does?
CSS display: none generates no layout box for the element or its descendants. position: absolute removes a box from normal flow but still displays it, positioned against its containing block.
What is the difference between display: none and visibility: hidden?
CSS display: none removes an element’s layout box and its space. visibility: hidden hides the element while preserving its box and space. Both normally hide the affected content from assistive technology, so neither is suitable for a visually hidden accessible label.
Sources
-
[1]
display(developer.mozilla.org)
-
[2]
width(developer.mozilla.org)
-
[3]
margin(developer.mozilla.org)
-
[4]
Block and inline layout in normal flow(developer.mozilla.org)
-
[5]
Mastering margin collapsing(developer.mozilla.org)
Read Next
How flexbox arranges items along one axis: the flex container, the main and cross axis, and the justify-content and align-items properties.
How CSS grid lays out two dimensions: grid-template-columns, rows, gaps between tracks, and placing items across the grid.
How CSS arranges boxes on the page: normal flow, flexbox for one axis, grid for two, and positioning to lift elements out of flow.