Display and normal flow

CSS · Essentials · 8 min

Normal flow is the default layout every other technique builds on or breaks out of.

Without any layout CSS, elements are arranged by normal flow: block boxes stack vertically, each taking the full available width; inline boxes sit side by side in lines of text and wrap like words.

The display property changes how a box takes part:

  • block: new line, full width, respects width/height and vertical margins.
  • inline: flows in text. width and height are ignored, and vertical padding and margins don't push other lines away.
  • inline-block: flows in text like a word but is sized like a block, which suits buttons and badges.
  • none: removes the element from layout and from the accessibility tree.
  • flex and grid: the element becomes a container that lays out its children; later lessons cover both.

display really has two parts: the outer type (how the box behaves with siblings: block or inline) and the inner type (how it lays out its children: flow, flex, grid). That's why inline-flex exists, an inline-level box whose children are a flex layout.

Hiding elements has options with different effects:

  • display: none: no space, not rendered, hidden from screen readers.
  • visibility: hidden: invisible but still takes up space.
  • opacity: 0: invisible, takes space, still clickable and focusable.

To hide something visually but keep it for screen readers, use a "visually hidden" utility class (clip-path plus a 1px size), not display: none.

Example

/* <p>Text <span class="badge">new</span> more text</p> */
.badge {
  display: inline-block;     /* sits in the line, but accepts padding and size */
  padding: 2px 8px;
  border-radius: 999px;
  background: #e0f2fe;
}

nav a { display: block; }    /* each link on its own full-width line */

.toolbar { display: inline-flex; gap: 4px; }  /* inline box, flex children */

.is-hidden { display: none; }

.visually-hidden {           /* hidden on screen, still read aloud */
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

Remember

  • Normal flow: blocks stack, inline boxes wrap in lines
  • Inline boxes ignore width and height; inline-block doesn't
  • display: none removes from layout and accessibility; visibility: hidden keeps space

Watch out for

  • Setting width on a span and wondering why nothing changes.

Check yourself

  1. Which hides an element but keeps its space in the layout?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/display