CSS Display Property: Block, Inline, Inline-Block, and Display None

Master the CSS display property. Learn the visual differences between block, inline, inline-block, and none, and how they affect the document flow.

Introduction

Before you can align components into grids or float sidebars beside articles, you must understand how individual elements behave in the browser's document flow. By default, some HTML tags stack vertically while others sit side-by-side.

This behavior is governed by the CSS display property. It defines the rendering box type of an element and determines how it behaves relative to surrounding elements. Changing the display state is the primary way we structure layout architectures.


What You Will Learn

  • How the default document flow handles page elements.
  • The differences between block, inline, and inline-block.
  • Hiding elements using display: none vs. visibility: hidden.
  • Practical use cases for modifying display properties.

Prerequisites


Detailed Explanation: Block vs. Inline vs. Inline-Block

Every HTML element has a default display value depending on its semantic type. Let's compare the three main flow behaviors:


1. Block Elements (display: block)

Block-level elements start on a new line and stretch horizontally to fill the full width of their parent container.

  • Default Tags: <div>, <p>, <h1> to <h6>, <ul>, <li>, <section>, <header>.
  • Sizing Math: You can declare explicit width and height properties. Vertical and horizontal padding/margins are fully respected.
span.make-block {
  display: block;
  width: 100%;
}

2. Inline Elements (display: inline)

Inline elements render side-by-side on the same line, only occupying as much horizontal space as their content assets require.

  • Default Tags: <span>, <a>, <strong>, <em>, <code>, <small>.
  • Sizing Constraints: You cannot set a width or height. Explicit declarations of width and height are ignored.
  • Margin/Padding Constraints: Horizontal padding and margins are respected. Vertical padding and margins are rendered on screen but do not push neighboring elements away, causing overlaps.

3. Inline-Block Elements (display: inline-block)

Inline-block is a hybrid. Elements sit side-by-side on the same line (like inline elements), but they respect explicit width, height, and vertical spacing values (like block elements).

  • Default Tags: <button>, <input>, <img>, <select>.
  • Sizing Math: All box-model properties (width, height, margin, padding) are fully respected.
a.button-link {
  display: inline-block;
  width: 180px;
  padding: 12px 24px;
}

Sizing Comparison Table

| Display Value | Starts New Line | Respects Width/Height | Respects Margins/Padding | | :--- | :--- | :--- | :--- | | block | Yes | Yes | Yes (all sides) | | inline | No | No | Horizontal only | | inline-block | No | Yes | Yes (all sides) |


Hiding Elements: display: none vs. visibility: hidden

If you need to hide an element on screen (for example, hiding a mobile navigation menu until a hamburger button is clicked), you have two primary methods:

1. Display None (display: none)

The element is completely removed from the rendering tree. It occupies no space on the screen, and neighboring elements shift to fill the gap.

.mobile-menu {
  display: none; /* Entirely gone from layout flow */
}

2. Visibility Hidden (visibility: hidden)

The element is hidden on screen, but it still occupies space in the document layout. It acts as an invisible block, leaving an empty gap.

.invisible-card {
  visibility: hidden; /* Hidden but preserves layout space */
}

Visual Learning Diagram (Mermaid)

graph TD
    subgraph Document Layout Flow
    DirectionBlock[display: block <br> Stacked vertically <br> Full width parent]
    DirectionInline[display: inline <br> Side-by-side flow <br> Width ignored]
    DirectionInlineBlock[display: inline-block <br> Side-by-side flow <br> Width respected]
    end

Code Examples

Example 1: Custom Inline Navigation Menu

Format bulleted list elements (blocks) into a horizontal navigation bar (inline-blocks):

.nav-list {
  list-style-type: none;
  padding: 0;
  margin: 0;
}

.nav-list__item {
  /* Change list elements from default block to inline-block */
  display: inline-block;
  margin-right: 20px;
}

.nav-list__link {
  /* Links are inline. Convert to block to style hover padding areas */
  display: block;
  padding: 8px 16px;
  text-decoration: none;
  background-color: #f1f5f9;
  border-radius: 4px;
}

Example 2: Toggle Visibility for Accessible Tooltips

Make tooltips that appear on focus using display properties:

.tooltip-container {
  position: relative;
  display: inline-block;
}

.tooltip-text {
  /* Start hidden and out of layout tree */
  display: none; 
  position: absolute;
  bottom: 125%;
  left: 50%;
  transform: translateX(-50%);
  background-color: #334155;
  color: white;
  padding: 8px;
  border-radius: 4px;
}

/* Reveal tooltip when hovering over parent container */
.tooltip-container:hover .tooltip-text {
  display: block;
}

Best Practices & Common Mistakes

  • Incorrect Inline Spacing: A common error is leaving standard <a> links inline, adding vertical padding (padding: 10px 15px;), and expecting it to push paragraphs down. The padding will overlap neighboring text blocks. Always declare display: inline-block on links meant to look like buttons.
  • Space Gap in Inline-Blocks: When using display: inline-block, browsers render a tiny horizontal whitespace gap (around 4px) between elements. This is caused by the line breaks or spaces in your HTML. To remove this gap, set font-size: 0 on the parent container, or use modern layout engines like Flexbox instead.

FAQs

Q: Does screen readers read elements with display: none? A: No. Elements styled with display: none or visibility: hidden are ignored by screen readers. If you want to hide text visually but keep it accessible for screen readers (e.g. "Screen Reader Only" text), use absolute clip positioning classes instead.

Q: What does display: flow-root do? A: display: flow-root creates a new block formatting context (BFC) for the element, which behaves like a normal block container but automatically wraps and clears all internal floated elements.


Summary

The CSS display property coordinates block structures. While block forces elements onto new lines, inline flows content horizontally (ignoring vertical dimensions), and inline-block allows sizing details while remaining side-by-side. Additionally, display: none removes components completely from layouts.


Related Articles

Next Tutorial

How do we offset elements dynamically from their default flow locations and lock them in place? Let's check: CSS Position Property.