Skip to main content

Block, inline and inline-block elements in HTML & CSS

display: block, display: inline, and display: inline-block control how elements occupy space and flow in the document.

Theory

TL;DR

  • Block = full-page ads: takes the whole line, stacks vertically, respects all box model properties.
  • Inline = words in a sentence: flows horizontally, ignores width/height, only left/right margins apply.
  • Inline-block = images in text: flows inline but respects width, height, and all margins.
  • Main difference: block forces line breaks and full width; inline ignores dimensions; inline-block allows both.
  • Decision rule: block for layout sections, inline for text spans, inline-block for buttons or icons in a row.

Quick example

html
<style> .block { display: block; background: lightblue; padding: 10px; margin: 10px; } .inline { display: inline; background: lightgreen; padding: 10px; margin: 10px; } .inl-block { display: inline-block; background: lightcoral; padding: 10px; margin: 10px; width: 120px; height: 50px; } </style> <!-- Stacks vertically, full width --> <div class="block">Block 1</div> <div class="block">Block 2 (below)</div> <!-- Flows side by side, ignores width/height --> <span class="inline">Inline 1</span> <span class="inline">Inline 2</span> <!-- Flows side by side, respects size --> <span class="inl-block">Inline-block 1</span> <span class="inl-block">Inline-block 2</span>

Block elements stack. Inline elements sit beside each other but won't accept width or height. Inline-block sits beside each other and does accept sizing.

Key difference

Block triggers a line break before and after, then expands to fill the container width. That's why <div> takes the full row even if its text is one word. Inline joins the surrounding text flow like a word in a sentence: no line break, no response to width or height. Inline-block is the middle ground. It stays in the line flow but creates a sized box, which is why buttons typically work this way.

When to use

  • Need something to stack vertically and fill width? Block. Sections, headers, article containers.
  • Styling part of a sentence or wrapping a link inside text? Inline. <span>, <a>, <em>.
  • Button, badge, or nav tab that needs padding and a fixed size but sits beside other elements? Inline-block.
  • Avoid setting width or height on inline elements - they have no effect.

Comparison table

Propertyblockinlineinline-block
Starts new lineYesNoNo
width / height respectedYesNoYes
Margin (all sides)YesLeft/right onlyYes
Padding (all sides)YesLeft/right onlyYes
Full width by defaultYesNoNo
When to useSections, containersText stylingButtons, badges, tabs

Common mistakes

Setting width/height on inline elements:

css
span { display: inline; width: 200px; height: 100px; } /* both ignored */

The browser ignores those properties on inline elements. Switch to inline-block if you need sizing.

Expecting vertical margins on inline elements:

html
<span style="margin-top: 20px;">Text</span>

Vertical margins on inline elements don't affect layout. Only margin-left and margin-right work. Use inline-block or add vertical-align.

The whitespace gap with inline-block:

html
<span style="display: inline-block; width: 100px;">A</span> <span style="display: inline-block; width: 100px;">B</span>

The newline between the tags renders as a ~4px gap. I've seen this break nav layouts more than once. Fix: set font-size: 0 on the parent, or remove all whitespace between the closing and opening tags.

Real-world usage

  • Bootstrap btn-group uses inline-block for side-by-side buttons (v5.3+).
  • GitHub's repo nav tabs are inline-block links with padding and borders.
  • Tailwind's inline-block utility appears in button and badge components.
  • Material UI's Chip component defaults to inline-flex, which behaves the same way for line flow.

Follow-up questions

Q: What is the default display value of <img>?
A: Inline. Images are replaced elements that flow like text characters but keep their intrinsic dimensions. That's why there's often a small gap below an image inside a container - it's baseline alignment, not a bug.

Q: What happens to inline-block children inside a flex container?
A: The flex formatting context takes over. display: flex on the parent overrides the inline flow of its children. The width and height you set on those children still apply.

Q: Why does vertical-align only work on inline and inline-block elements?
A: It aligns elements within line boxes. Block elements create their own lines and have no line box to align against.

Q: (Senior) If you set display: block on a grid item, does it affect grid layout?
A: No. Grid items ignore their own display value for positioning because the grid formatting context takes over. But it does affect the item's internal formatting: its own children now flow as block. Mention the containing block concept here and you'll stand out.

Examples

html
<nav style="background: #f6f8fa; padding: 1rem;"> <a href="#" style="display: inline-block; padding: 0.5rem 1rem; margin-right: 0.5rem; background: white; border: 1px solid #ddd; text-decoration: none;">Code</a> <a href="#" style="display: inline-block; padding: 0.5rem 1rem; margin-right: 0.5rem; background: white; border: 1px solid #ddd; text-decoration: none;">Issues</a> <a href="#" style="display: inline-block; padding: 0.5rem 1rem; background: white; border: 1px solid #ddd; text-decoration: none;">Pull requests</a> </nav>

Each link needs padding and a border but must stay in one row. Pure inline would ignore padding dimensions in layout; block would stack each link on its own line. inline-block gives each link a proper box while keeping them side by side. This is the pattern behind GitHub's repo navigation.

User avatar with name

html
<style> .avatar-wrap { display: inline-block; vertical-align: middle; margin-right: 8px; } .avatar-wrap img { display: block; width: 32px; height: 32px; border-radius: 50%; } .username { display: inline; font-weight: bold; } </style> <span class="avatar-wrap"> <img src="avatar.png" alt="User avatar"> </span> <span class="username">john_doe</span>

The image wrapper is inline-block so it can have a fixed size and vertical-align: middle to align with the text beside it. The username is plain inline because it needs no sizing - it flows as text.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.

Finished reading?