Home Module 04 Display Property

1. Introduction

Every HTML element has a default display value — and this controls how it behaves in the page flow. A <div> takes up the full line width. A <span> sits inline with text. An <img> acts like an inline element.

The display property is one of the most important in CSS because it determines:

  • Whether the element starts on a new line or flows with text
  • Whether you can set a width and height on it
  • Whether its children are arranged using Flexbox or Grid
  • Whether the element renders at all

In this lesson we cover all the key display values you need to know.

2. Theory

display: block

Block elements:

  • Start on a new line
  • Take up the full width of their parent
  • Respect width, height, margin, padding

Default block elements: div, p, h1-h6, ul, ol, li, header, main, section, article, footer, form

div { display: block; } /* already default — no need to set this */

display: inline

Inline elements:

  • Flow within text — no new line
  • Width and height are ignored — sized to content
  • Horizontal padding and margin work; vertical is unpredictable

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

span { display: inline; } /* already default */

/* You can make a block inline: */
p { display: inline; } /* paragraphs flow inline — rarely useful */

display: inline-block

The best of both worlds:

  • Flows inline (no new line) like inline elements
  • Accepts width, height, vertical margin/padding like block elements
.badge {
  display: inline-block;
  padding: 4px 12px;
  background: #dbeafe;
  color: #1d4ed8;
  border-radius: 999px; /* pill shape */
  font-size: 0.75rem;
  font-weight: 600;
}

display: none

Completely removes the element from the page — it takes up no space and is invisible. Different from visibility: hidden which hides but preserves space.

.modal { display: none; }           /* hidden — no space taken */
.modal.is-open { display: block; } /* show when class added by JS */

/* vs */
.tooltip { visibility: hidden; }   /* invisible but still takes up space */
.tooltip:hover { visibility: visible; }

display: flex

Makes the element a flex container. Its children (flex items) are arranged in a row or column using the Flexbox layout model. Covered fully in Module 05.

.nav {
  display: flex;
  gap: 16px;
  align-items: center;
}

display: grid

Makes the element a grid container. Its children are placed on a two-dimensional grid. Covered fully in Module 06.

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

display: inline-flex and inline-grid

Like flex/grid but the container itself behaves as an inline element (sits in text flow).

.tag {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
}

display: table

Makes an element behave like a table. Mostly replaced by Flexbox and Grid today, but occasionally used for centering tricks.

visibility: hidden vs display: none

PropertyVisible?Takes up space?Accessible to screen readers?
display: noneNoNoNo
visibility: hiddenNoYesNo
opacity: 0NoYesYes (still clickable!)

3. Real World Example

The display property is used constantly in real code:

  • display: flex — navigation bar, button groups, card headers
  • display: grid — photo gallery, feature grid, dashboard layout
  • display: none — mobile menu (hidden until hamburger clicked), modal (hidden until triggered), tooltips
  • display: inline-block — pill badges, tags, inline buttons
  • display: block on <a> — makes the entire link card clickable area

4. Code Example

/* Navigation: block by default, changed to flex */
.navbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 24px;
  height: 64px;
  background: #1e293b;
}

/* Nav links: normally inline, stay inline */
.nav-link {
  color: white;
  text-decoration: none;
  padding: 8px 12px; /* needs inline-block for padding to work perfectly */
  display: inline-block;
}

/* Badges: inline-block for sizing + inline flow */
.badge {
  display: inline-block;
  padding: 2px 10px;
  background: #dbeafe;
  color: #1e40af;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
  vertical-align: middle;
}

/* Modal: hidden by default */
.modal-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  place-items: center; /* needs display: grid or flex */
}

.modal-overlay.is-open {
  display: grid; /* shows and uses grid for centering */
}

/* Mobile nav hidden */
.mobile-nav {
  display: none;
}

@media (max-width: 768px) {
  .desktop-nav { display: none; }
  .mobile-nav { display: block; }
}

/* Image — make it block to remove baseline gap */
img {
  display: block;
  max-width: 100%;
}

5. Code Breakdown

display: flex on .navbar
Changes the navbar to a flex container, allowing align-items: center (vertical centering) and justify-content: space-between (pushes logo left, links right). This is impossible to do cleanly with block/inline.
display: inline-block on .nav-link
Links are inline by default. inline-block lets them have consistent padding and a clickable area while still flowing horizontally in the flex container.
vertical-align: middle on .badge
When inline/inline-block elements are mixed with text, the default vertical alignment is the text baseline. middle centres the badge relative to the surrounding text line height.
display: grid on .modal-overlay.is-open
When the modal is shown, the overlay needs to centre its content. display: grid; place-items: center; is the most concise way to perfectly centre an element both vertically and horizontally.
display: block on img
Images are inline by default, which causes a small gap at the bottom (the text baseline gap). Making them display: block removes this gap — a very common CSS reset.

6. Common Mistakes

  • Setting width/height on inline elements and wondering why it does not work. <span> and <a> are inline by default. They ignore width and height. Change to inline-block or block.
  • Confusing display: none and visibility: hidden. none removes the element from flow entirely (no space). hidden makes it invisible but preserves its space. Use none for toggling menus/modals.
  • Not knowing that opacity: 0 elements are still clickable. An element with opacity: 0 is invisible but still receives click events — can cause confusing bugs. Use pointer-events: none alongside it if needed.
  • Forgetting that inline elements cannot have meaningful vertical margin. Vertical margins on inline elements are unpredictable. Convert to block or inline-block for spacing control.

7. Best Practices

  • Use display: flex for one-dimensional layouts (rows or columns) — navigation bars, button groups, card headers.
  • Use display: grid for two-dimensional layouts — galleries, dashboards, form layouts.
  • Use display: none for toggling visibility — it removes the element completely from layout and accessibility tree.
  • Set display: block on images in most contexts to prevent the baseline gap.
  • Avoid display: table — Flexbox and Grid have replaced table layout.

8. Practice Exercise

  1. Create an <a> tag with just display: inline (default). Notice you cannot control its height with height: 40px. Switch to inline-block and confirm height now works.
  2. Create a modal: a div overlay (display: none) with a centred content box inside. Add a button that adds class is-open. Style .modal.is-open { display: grid; place-items: center; }.
  3. Create three <span> elements styled as badges (pill shape, coloured background). Use inline-block.
  4. Create a simple navbar using display: flex with a logo on the left and 4 links on the right.

9. Assignment

Build a page that demonstrates all the key display values:

  • A navbar using display: flex
  • A hero section with centred content using display: grid; place-items: center;
  • A tag/badge system using display: inline-block
  • A "show/hide" button that toggles a display: none panel (use JavaScript or just show both states with CSS classes)
  • A three-column feature section using display: grid

10. Interview Questions

Q1: What is the difference between block, inline, and inline-block?

Answer: Block elements start on a new line and fill the full parent width — you can set width, height, and all margins. Inline elements flow within text, ignore width/height, and vertical margin is unreliable. Inline-block sits inline but accepts all box model properties — it is a hybrid.

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

Answer: display: none completely removes the element from the page — it takes up no space and is not rendered. visibility: hidden makes the element invisible but it still occupies its space in the layout, leaving a blank gap.

Q3: How do you horizontally centre an inline element?

Answer: Add text-align: center to the parent element. This works for inline and inline-block children. For block elements, use margin: 0 auto with an explicit width.

Q4: Why might you add display: block to an image?

Answer: Images are inline by default, which causes a small gap at the bottom due to text baseline alignment. Making them display: block removes this unwanted gap — useful inside containers where you want no spacing below the image.

Q5: What does display: flex do?

Answer: It turns the element into a flex container, enabling the Flexbox layout model for its direct children. Children become flex items and can be arranged, aligned, and distributed using properties like flex-direction, justify-content, and align-items.

11. Additional Resources

  • MDN Web Docs — display property (search "MDN CSS display")
  • CSS-Tricks — A Complete Guide to Flexbox (search "css-tricks flexbox guide")
  • MDN — Block and inline layout (search "MDN block inline layout")
  • web.dev — Learn CSS Display (search "web.dev learn css display")