Ad – 728×90
📐 CSS Layout

CSS Display – The Property That Controls Everything

The display property is the most important layout property in CSS. It determines how an element participates in the flow of the page — whether it stacks vertically, flows inline with text, becomes a flex container, or disappears entirely. Every HTML element has a default display value, and changing it unlocks entirely different layout behaviours. In this lesson you will learn every display value, what each one does, and when to use it.

⏱️ 20 min read 🎯 Beginner 📅 Updated 2026 👁️ Lesson 1 of 6

The Two Fundamental Types: Block vs Inline

Before modern layout modes (flexbox, grid), every HTML element was either block or inline. Understanding this distinction is still fundamental:

display: block

Block elements:

  • Start on a new line
  • Stretch to fill the full width of their container
  • Respect width, height, margin, padding on all sides
  • Stack vertically, one below the other

Default block elements: <div>, <p>, <h1><h6>, <section>, <article>, <header>, <footer>, <ul>, <li>, <form>

CSS + HTML – block
.box { display: block; background: #e8f4fd; padding: 12px; margin-bottom: 8px; }
▶ Each fills the full width and stacks
Block element 1
Block element 2
Block element 3

display: inline

Inline elements:

  • Flow within text — like words in a sentence
  • Only take up as much width as their content
  • Do not start a new line
  • width and height are ignored
  • Vertical margin and padding are partially ignored (don't push other elements)

Default inline elements: <span>, <a>, <strong>, <em>, <img>, <button>, <input>, <label>, <code>

▶ Flow side by side in text
Inline 1 Inline 2 Inline 3

display: inline-block

The best of both worlds:

  • Flows inline (doesn't force a new line)
  • Respects width, height, vertical margin, and padding like a block

Use cases: navigation links, badges, buttons that should sit inline but need sizing control.

CSS
.nav-link {
  display: inline-block;
  padding: 8px 16px;
  margin-right: 4px;
  background: #1572B6;
  color: white;
  border-radius: 4px;
  text-decoration: none;
}
▶ Side by side with full padding/size control
Item 1
Item 2
Item 3
Ad – 336×280

display: none – Hiding Elements

display: none removes the element from the page entirely — it takes up no space, is not visible, and is not announced by screen readers.

CSS
/* Remove from layout entirely */
.hidden { display: none; }

/* Common pattern: toggle with JavaScript */
.modal { display: none; }
.modal.is-open { display: flex; }

/* Responsive hiding */
@media (max-width: 768px) {
  .desktop-only { display: none; }
}
💡
display: none vs visibility: hidden vs opacity: 0

display: none — element removed from layout, takes no space, not readable by screen readers.
visibility: hidden — element invisible but still occupies space. Not readable by screen readers.
opacity: 0 — element invisible but still occupies space AND is readable by screen readers. Can receive pointer events unless pointer-events: none is also set.

display: flex

Turns the element into a flex container. Its direct children become flex items that can be arranged horizontally or vertically, aligned, and distributed with powerful properties.

CSS
.nav {
  display: flex;
  gap: 16px;
  align-items: center;
  justify-content: space-between;
}

.card-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
}

Flexbox is covered in depth in the next lesson. It is the most-used layout tool in modern CSS.

display: grid

Turns the element into a grid container. Creates a two-dimensional layout system with rows and columns.

CSS
.layout {
  display: grid;
  grid-template-columns: 250px 1fr;
  grid-template-rows: auto 1fr auto;
  min-height: 100vh;
}

.card-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}

CSS Grid is covered in detail later in this course.

Other display Values

CSS – Additional display values
/* flow-root — creates a new block formatting context
   Useful to contain floats and prevent margin collapse */
.clearfix { display: flow-root; }

/* contents — element's box is removed but children render normally
   Useful for semantic wrapper elements that shouldn't affect layout */
.wrapper { display: contents; }

/* table values — make non-table elements behave like table cells */
.row  { display: table-row; }
.cell { display: table-cell; vertical-align: middle; }
/* Rarely needed — flexbox/grid are almost always better */

/* list-item — element generates a block box with a list marker */
.custom-list-item { display: list-item; list-style: disc; }

/* inline-flex — flex container that flows inline */
.tag { display: inline-flex; align-items: center; gap: 4px; }

/* inline-grid — grid container that flows inline */
.mini-grid { display: inline-grid; grid-template-columns: 1fr 1fr; }

Default Display Values by Element

HTML elements and their default display
BLOCK by default:
  div, p, h1-h6, section, article, header, footer, main, nav,
  aside, ul, ol, li, dl, dt, dd, form, fieldset, blockquote, pre,
  table, hr, figure, figcaption

INLINE by default:
  span, a, strong, em, b, i, u, s, small, code, kbd, mark,
  abbr, cite, q, sub, sup, label, button, input, select, textarea,
  img, svg, video, canvas

NONE by default:
  script, style, head, meta, link, title
ℹ️
Changing display doesn't change semantics

Setting display: block on a <span> makes it visually behave like a block, but it is still a <span> semantically — screen readers still treat it as an inline element. Similarly, setting display: inline on a heading doesn't change its heading level for accessibility. Use the right HTML element for the right semantic purpose, then adjust display for visual layout.

📋 Summary

  • block — full width, new line, respects all box model properties. Default for divs, headings, paragraphs.
  • inline — flows in text, no width/height, vertical margin ignored. Default for spans, links.
  • inline-block — inline flow + full box model support. Great for buttons and nav items.
  • none — removes element from layout entirely. Takes no space. Not accessible.
  • flex — one-dimensional layout. Best for rows/columns of items.
  • grid — two-dimensional layout. Best for complex page layouts.
  • flow-root — contains floats, prevents margin collapse.
  • contents — element box removed, children rendered normally.

Frequently Asked Questions

What is the difference between display: none and visibility: hidden? +

display: none removes the element completely — it takes no space, other elements reflow to fill its position, and screen readers do not announce it. visibility: hidden makes the element invisible but it still occupies its space in the layout (a blank gap remains). Neither triggers layout reflow when toggled with JavaScript — display: none does trigger reflow, while visibility: hidden only triggers repaint. For accessible hiding (visually hidden but readable by screen readers), use the .sr-only class pattern instead of either property.

When should I use inline-block instead of flexbox? +

inline-block is useful for simple cases: a row of navigation links, a series of badges or tags, or a button that sits inline within paragraph text. It's simpler to set up than flex when you just need elements side by side. Use flexbox when you need alignment control (vertical centering, space-between), wrapping behavior, or any kind of responsive distribution. In modern CSS, flexbox handles most cases where inline-block was previously used.

Why does my div not center with margin: auto? +

Two requirements for margin: 0 auto centering: (1) The element must have display: block (or block-level). Inline elements can't be centered this way. (2) The element must have an explicit width smaller than its container — without a width, a block stretches to 100% and has no space to distribute. Fix: set display: block and add max-width: 800px; width: 100%; margin: 0 auto.

What does display: contents do? +

display: contents makes the element's own box disappear from the layout, but its children render as if they were direct children of the element's parent. This is useful when you have a semantic wrapper element (like a <ul>) that you want to participate in a flex or grid layout without the wrapper creating an extra layout layer. Be aware: it removes the element from the accessibility tree in some browsers — use with caution.