Command Palette

Search for a command to run...

Hectal
PHASE 5Beginner ~22 min· topic 4 of 8

Topic 5.4

The display Property

In one line

display decides what kind of box an element makes: a block that takes a full row, an inline box that flows inside text, an inline-block mix of both, no box at all (none, contents), or a block that contains its own layout (flow-root).

Think of it like this

Furniture and words on a page. A block is like a bookshelf: it takes a whole wall to itself, and the next shelf goes below it. An inline box is like a word in a sentence: it sits next to other words and wraps to the next line when the line is full. An inline-block is like a sticker in a sentence: it sits in the line like a word, but it has its own fixed size.

Words you'll meet

New words in this topic, in plain English. Come back here whenever one feels fuzzy.

display
The CSS property that decides what kind of box an element makes and how its children are laid out.
Block box
A box that starts on a new line and fills the full width of its parent, like a paragraph.
Inline box
A box that flows inside a line of text, like a word. It ignores width and height.
inline-block
A box that sits in a line like a word but can have its own width, height and vertical spacing.
Baseline
The invisible line that letters sit on. Letters like g and y hang below it.
display: none
Remove the element and its children completely: no box, no space, not read by screen readers.
display: contents
Remove the element's own box but keep its children, which act as children of its parent.
Outer and inner display
Outer: how the box sits among its siblings (block or inline). Inner: how it lays out its children (flow, flex, grid…).

Step by step

01See the defaults

Write a paragraph containing a link and a <strong> word. The paragraph is block (full width, its own line); the link and the strong word are inline (they flow with the text). You haven't written any CSS: the browser's default stylesheet set these.

index.htmlwhole filehtml
<p>Read the <a href="#">guide</a> before you <strong>start</strong>.</p>

02Try to size an inline box

Give the link width: 200px; height: 50px. Nothing changes: inline boxes ignore width and height. Add padding: 20px and the background grows up and down over the neighbouring lines, but the lines don't move apart.

03Switch it to inline-block

Add display: inline-block. Now the width, height and vertical padding all work, the line grows to fit it, and it still sits inside the sentence.

style.csswhole filecss
a {
  display: inline-block;
  width: 200px;
  padding: 8px;
}

04Hide things three different ways

display: none removes it and its space. visibility: hidden keeps the space but shows nothing. display: contents removes only the wrapper's own box and keeps the children.

Hide things three different waysdiagram
Rendering diagram…

05Contain a float with flow-root

A floated image (Topic 6.4) inside a short box hangs out of the bottom of its parent, because floats don't add to the parent's height. display: flow-root on the parent makes it grow to contain the float.

style.csswhole filecss
.media {
  display: flow-root; /* contains the floated .thumb */
}
.thumb {
  float: left;
}

Try it yourself

  1. 1

    Turn the span into a block

    In the first example, add display: block to .inl. Predict: does it now take 200px, and does it still sit in the sentence? (It uses the width, but breaks the sentence: a block always starts a new line.)

  2. 2

    Swap visibility and display

    In the second example, change .ghost to display: none. Predict the second log line before running.

  3. 3

    Remove flow-root

    In the third example, delete the .root rule. Both lines should now print false, and the two orange squares stack strangely.

Code & diagrams

block, inline and inline-block side by side New tab

The parent's content area is 300px wide (its 1px border sits outside that), and the block fills all of it. The inline span ignores width and height; the inline-block uses them (plus 6px padding on each side).

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

block div fills its parent: 300
inline span uses width 200? false
inline-block outer width: 212
inline-block outer height: 52
none vs visibility: hidden vs contents New tab

Look at the preview: a 44px blank gap for the hidden box, no border around the pink text, and the first box is gone entirely.

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

display: none height: 0
visibility: hidden height: 44
display: contents box height: 0
its child still shows: true
flow-root contains a float New tab

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

plain contains the float: false
root contains the float: true

Break it on purpose

Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.

Break #1

Give a link a height

Write nav a { height: 48px; width: 120px; background: navy; color: white; } for a row of navigation links.

terminal
$ the page shows
── what you'll see ──
The links stay exactly as tall and wide as their text; the height and width do nothing

Break #2

Gaps between inline-block cards

Put four inline-block cards with width: 25% on separate lines in the HTML.

terminal
$ the page shows
── what you'll see ──
Only three cards fit per row; there is a small gap between each card

Break #3

display: contents on a button

Set display: contents on a <button> to remove its box from a grid.

terminal
$ Accessibility tree
── what you'll see ──
In some older browsers, the button stops being announced as a button or can't be focused

Myth vs fact

Myth

An element's tag decides if it's block or inline.

Fact

The tag only sets the browser's default display. CSS can make a span a block and a div inline. What's fixed is the HTML content model (what may go inside what), not the box type.

Myth

display: none and visibility: hidden are the same.

Fact

none removes the box and its space; visibility: hidden keeps the space. Both hide the element from screen readers. A child of a visibility: hidden parent can be shown again with visibility: visible; a child of a display: none parent can't.

Myth

Inline elements can't have padding.

Fact

They can, and it's painted, but vertical padding doesn't push other lines away. Horizontal padding does take space in the line.

Pro corner

Extra depth for experienced readers. New to this? Skip it for now and come back later.

  • ▸

    The multi-keyword syntax (display: inline flex, display: block flow-root) is supported in all major browsers since 2023. The one-word values remain valid and are what most code uses.

  • ▸

    display: none elements are skipped by layout and paint, and by the accessibility tree. For content that should be hidden visually but read by screen readers, use a "visually hidden" class (clip it to 1px) instead; for content hidden from everyone but kept rendered for speed, look at content-visibility: hidden.

  • ▸

    Changing display triggers layout. Toggling between none and something else is cheap for small elements but expensive for large subtrees, because the whole subtree is built or torn down. Note too that display can't be smoothly transitioned in older browsers; newer ones support transition-behavior: allow-discrete for that.

  • ▸

    The HTML hidden attribute is implemented in the default stylesheet as display: none. A CSS rule like .card { display: flex } overrides it, so the element shows despite hidden. Many resets add [hidden] { display: none !important; }.

Remember this

  1. 1

    display: block boxes start on a new line, stretch to fill the full width of their parent (unless you give them a width), and stack top to bottom. They respect width, height, and all margins and padding. div, p, h1–h6, ul, section and form are block by default (the browser's built-in stylesheet sets that).

  2. 2

    display: inline boxes sit inside a line of text, side by side, and are only as wide as their content. They **ignore width and height. Their left and right padding, border and margin push neighbours sideways, but their top and bottom padding and margin don't move other lines**: vertical padding and borders are painted (they may overlap the line above or below) yet take no space. span, a, strong, em and code are inline by default.

  3. 3

    display: inline-block boxes sit in a line like inline boxes, but inside they behave like blocks: width, height, and vertical padding and margin all work and push other lines away. They are useful for buttons, badges and tags in a sentence. One gotcha: the whitespace (spaces and line breaks) between inline-block elements in your HTML becomes a visible gap, and inline-blocks sit on the text baseline, leaving a few pixels below them for letters like g and y.

  4. 4

    display: none removes the element and everything inside it from the page entirely: no box, no space, not clickable, and hidden from screen readers. Compare visibility: hidden, which hides the element but keeps its space. display: contents does something different again: the element's own box disappears (no background, border, padding or size), but its children stay and act as if they were children of the element's parent. It's handy for making a wrapper invisible to a flex or grid layout.

  5. 5

    display: flow-root makes a normal block box that also starts a new block formatting context (BFC, see Topic 5.3). That means it fully contains floated children (its height grows to wrap them) and its children's margins can't collapse through it. It was added to CSS exactly for this, replacing old hacks like the "clearfix" (Topic 6.4 — Floats) and overflow: hidden.

  6. 6

    display really sets two things: the outer type (how the box takes part in its parent's layout: block or inline) and the inner type (how its children are laid out: flow, flow-root, flex, grid, table). Modern CSS lets you write both: display: block flow is block, display: inline flow-root is inline-block, and display: inline flex is inline-flex. The one-word values you know are shortcuts. Flexbox (Phase 7) and Grid (Phase 8) are display values too.

Explain it without notes

01

What are the differences between block, inline and inline-block boxes?

02

Compare display: none, visibility: hidden and display: contents.

03

What problem does display: flow-root solve?

04

What do the outer and inner display types mean? Give examples.

Practice

01

Make three <a> tags look like 120px-wide, 40px-tall buttons in a row, without Flexbox. Log the offsetWidth of the first.

02

A .list wrapper must disappear from layout while its three .item children stay. Log the wrapper's getBoundingClientRect().height and the number of visible items.

Trade-offs

  • ↔

    inline-block was the old way to put boxes in a row; it works everywhere but brings whitespace gaps and baseline alignment. Flexbox and Grid replace it for layout; keep inline-block for things that truly sit in text.

  • ↔

    display: contents makes wrappers disappear from layout, which helps flex and grid, but you lose the wrapper's background, border and padding, and must test accessibility on semantic elements.

Done when you can

  • I can say how block, inline and inline-block boxes differ.

  • I can choose between display: none, visibility: hidden and display: contents.

  • I can use flow-root to contain floats and stop margin collapse.

  • I can explain the whitespace gap between inline-block elements.

  • I can read two-value display syntax like inline flex.