Normal Flow and Display

Introduction

Before Flexbox and Grid, every page already has a default layout system: normal flow. If you understand how elements flow by default and how display changes that behavior, most layout bugs become much easier to solve. This chapter explains normal flow and the practical use of common display values in real UI work.

Prerequisites

  • Basic HTML structure knowledge
  • Basic box model and sizing knowledge
  • Familiarity with CSS selectors and simple component styling

What Is Normal Flow?

Normal flow is the browser's default layout behavior when no special positioning or advanced layout mode is applied.

In normal flow:

  • block-level elements stack vertically
  • inline content flows inside lines
  • elements occupy space in document order

Example HTML:

html
<h1>Page Title</h1>
<p>First paragraph.</p>
<p>Second paragraph.</p>

By default, these blocks appear top to bottom.

Block vs Inline in Normal Flow

Block-level behavior

Block boxes usually:

  • start on a new line
  • expand to available inline width
  • stack vertically

Common examples: div, p, section, article, h1-h6, ul, li.

Inline behavior

Inline boxes usually:

  • stay within text flow
  • do not start a new line automatically
  • occupy only needed content width

Common examples: span, a, strong, em, code.

The display Property

display defines how an element participates in layout.

Most common values:

  • block
  • inline
  • inline-block
  • none
  • flex (later chapter)
  • grid (later chapter)

Understanding the first four is essential before advanced layouts.

display: block

Forces element to behave like a block box.

css
a.cta {
  display: block;
  width: fit-content;
  padding: 0.6rem 1rem;
}

Useful when:

  • you want line breaks around the element
  • you want block spacing behavior
  • you need easier width/margin control

display: inline

Forces element to behave like inline text content.

css
h2 {
  display: inline;
}

Be careful:

  • width/height usually do not behave like block boxes
  • vertical margin/padding behavior differs from block context

Use inline mostly for small text-level adjustments, not major layout.

display: inline-block

inline-block combines features:

  • stays in inline flow (can sit next to text/elements)
  • supports width/height/padding like a box
css
.tag {
  display: inline-block;
  padding: 0.25rem 0.6rem;
  border-radius: 999px;
  background: #e2e8f0;
}

Useful for:

  • badges
  • chips
  • button-like inline elements

display: none

Removes element from layout and rendering flow.

css
.is-hidden {
  display: none;
}

Behavior:

  • element does not occupy space
  • siblings reflow as if element is absent

Common use:

  • conditionally hidden UI sections
  • responsive toggles (with caution)

Accessibility note:

  • display: none content is generally not accessible to assistive technologies while hidden.

visibility: hidden vs display: none

They are not the same:

css
.ghost {
  visibility: hidden;
}
  • visibility: hidden: invisible but still occupies layout space
  • display: none: removed from layout space

Choose intentionally based on whether layout space should remain reserved.

Natural Width Behavior in Normal Flow

Block elements often fill available width unless constrained:

css
.panel {
  max-width: 720px;
}

Inline elements size to content. If you need width control for an inline element, consider inline-block or block.

Inline Formatting Context Basics

Inside text flow:

  • text wraps at available width
  • inline elements align with text baseline by default
  • line-height affects vertical rhythm

This explains common alignment surprises between icons and text. You can adjust with:

  • vertical-align
  • line-height tuning

Why Normal Flow Still Matters with Flex/Grid

Even when using Flexbox/Grid:

  • child content still has typography flow
  • margins/padding still apply
  • hidden elements still affect semantics and interaction logic

Normal flow is the foundation beneath advanced layout systems.

Tip

Default First, Then Override

Start with semantic HTML and normal flow behavior. Add layout overrides (flex, grid, positioning) only where needed.

Common Mistakes

MistakeWhy it hurtsBetter approach
Using inline for large layout blocksWidth/height control becomes awkwardUse block or layout containers
Hiding content with display: none without logic checksMissing UI/function statesEnsure state handling is explicit
Using inline-block for full page layoutHard spacing/alignment managementUse Flexbox/Grid for larger layouts
Not understanding reserved space behaviorUnexpected blank gapsCompare visibility: hidden vs display: none
Styling all div elements globallySide effects across pageUse classes and scoped selectors

Mini Exercise

  1. Create a heading, paragraph, link, and badge element
  2. Toggle link between inline, inline-block, and block
  3. Add width and padding and observe behavior changes
  4. Hide one section with visibility: hidden, then with display: none
  5. Inspect layout differences in DevTools

FAQ

Is block/inline classification outdated?

The web platform has evolved, but this model is still useful and foundational for understanding default behavior.

Should I use inline-block for navigation menus?

You can for small cases, but Flexbox is usually cleaner and more maintainable for navigation layout.

Does display: none remove the element from the DOM?

No. It stays in the DOM tree but is removed from layout and rendering.

Why can't I set width on an inline element reliably?

Inline formatting rules prioritize text flow; width/height do not behave like block boxes there.

How do I debug display problems quickly?

Inspect the element in DevTools, check computed display, and toggle candidate values live to observe layout changes.