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.widthandheightare 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.flexandgrid: 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.