Skip to content

Display & Normal Flow

Before you can control layout, you need to understand what happens when you do nothing. Browsers have a built-in system for placing elements on a page. It is called normal flow — and it is not random. It follows two simple rules based on an element’s default display type.

Every HTML element is either a block or an inline element by default.

Block elements behave like stacked horizontal shelves. Each one takes up the full width available, and a new one always starts on a new line — regardless of how short its content is. Think of them as Figma frames with “Fill container” width and “Hug contents” height, stacked vertically in auto-layout.

Examples: <div>, <p>, <h1><h6>, <section>, <article>

Inline elements flow with text. They sit side-by-side and only take up as much width as their content requires. They do not break onto a new line. Think of them as individual text runs or icons inside a line of text.

Examples: <span>, <a>, <strong>, <em>, <img>

You can override any element’s default behaviour with the display property:

ValueWhat it does
blockFull-width shelf, starts on a new line
inlineFlows with text, no width/height control
inline-blockFlows with text, but you can set width and height
flexActivates Flexbox on the children
gridActivates Grid on the children
noneHides the element completely (not just invisible — removed from layout)

The editable example below has a mix of block and inline elements. Try changing .label from display: inline to display: inline-block and add width: 100px — notice how you can now control its size. Then try display: block to see it jump to its own line.

When you reach for Flexbox or Grid, you are replacing the normal-flow rules for that element’s children. The display property is the on/off switch. Understanding what normal flow looks like makes it immediately obvious why adding display: flex to a container changes everything — you are opting out of the default stacking rules.

What does a block element do by default?
Which display value lets an element flow with text AND accept a fixed width?
What does `display: none` do?
Which of these is an inline element by default?