Learn CSS · Lesson 3 of 7 · 6 min

Block vs inline

Before you can position anything, you need to know how elements take up space on their own. In normal flow there are two fundamental kinds of box: block boxes that stack down the page, and inline boxes that flow along with text. Almost every layout surprise traces back to which of these an element is.

Block boxes: stack down the page

A block box starts on a new line and, by default, takes up the full available width of its parent, no matter how little content it holds. Stack two of them and they sit one above the other, each claiming its own row. Block boxes respect the whole box model, so width, height, and margin and padding on all four sides all work as you would expect.

Most structural elements are block by default: <div>, <p>, <h1> through <h6>, <section>, <article>, <ul> and <li>. They are the scaffolding of a page.

block
block box, fills the width
block box, next one drops below
Two block boxes: each fills the row and the next starts on a new line.
.note {
  display: block;     /* the default for div, p, h1 ... */
  width: 200px;       /* honoured */
  padding: 12px;      /* honoured on all four sides */
  margin: 16px 0;     /* top and bottom margins both apply */
}

Inline boxes: flow with the text

An inline box does not start a new line. It sits in the text stream right where it appears, takes up only as much width as its content needs, and lets the next inline thing follow on the same line, wrapping to the next line only when it runs out of room (just like words in a sentence do).

The catch that trips everyone up: an inline box ignores width and height entirely, and it ignores top and bottom margins. You can set left and right margin and padding, but you cannot give a plain <span> a height. Common inline elements are <span>, <a>, <strong>, <em> and <img>.

inline

These inline boxes sit on one line and wrap like words do.

Inline boxes flow together and wrap. The first one tries width: 500px and is ignored.
.tag {
  display: inline;
  width: 500px;       /* IGNORED, width does nothing */
  height: 40px;       /* IGNORED, height does nothing */
  margin: 30px;       /* only left/right apply; top/bottom ignored */
  padding: 4px 8px;   /* left/right push siblings; top/bottom overflow */
}

Inline-block: the best of both

Sometimes you want a box that sits inline next to its neighbours but still accepts a width, a height, and full padding and margin on every side. That is display: inline-block. It flows like an inline element (boxes line up horizontally and wrap) yet behaves like a block element on the inside (the whole box model applies).

This is the classic choice for things like navigation items, tags, badges, and buttons laid out in a row, where you want each one to have a real size and consistent vertical padding while still flowing left to right. (These days flexbox often handles that job, but inline-block is the original tool and still useful.)

inline-block
Home Gallery Tools About
Inline-block boxes flow in a row but each keeps a set width, height and padding.
.nav-item {
  display: inline-block;
  width: 96px;        /* honoured */
  padding: 10px 0;    /* honoured on all four sides */
  text-align: center; /* now a real box you can size */
}

The display property is the switch

Every element has a default, but you are never stuck with it. The display property is the single switch that decides which kind of box an element generates. The three values from this lesson are:

  • display: block, full-width box, starts on a new line, full box model.
  • display: inline, flows with text, sized by content, ignores width/height and top/bottom margin.
  • display: inline-block, flows inline, but accepts width, height and the full box model.

The same property has a few more values you will meet soon. display: none removes the element from the page entirely (it takes up no space at all), while display: flex and display: grid turn an element into a powerful layout container for its children. Those get full lessons of their own in flexbox and grid.

Choosing between them

A simple way to decide:

  • Reach for block when the element is a structural chunk that should sit on its own row: a section, a card, a paragraph, a heading.
  • Leave things inline when they belong inside a sentence and should flow with the words: a link, an emphasized phrase, an inline icon.
  • Use inline-block when you want several items in a row that each need a real size, such as nav links, tags or buttons, and you are not yet reaching for flexbox.

One more tip: if you ever set width or height on something and the number is simply ignored, the element is almost certainly inline. Switching it to inline-block (or making its parent a flex container) is usually the fix. This connects straight to the box model, where those width and height values actually live.

Practice

Two minutes each, and each one locks in a single idea. Use a blank CodePen, your browser's DevTools, or one of our tools to experiment:

  1. Put two <span> elements next to each other and confirm they share one line. Now set both to display: block and watch them stack. You just changed how they take up space.
  2. Give a <span> a width: 300px and a height: 80px and confirm both are ignored. Then add display: inline-block and watch the size finally take effect.
  3. Build a row of four nav items using display: inline-block with a fixed width and vertical padding. Then try the same with the items left as plain inline and notice why the padding looks broken.

The mental model to keep

  • Block boxes start on a new line, fill the width, and respect the full box model.
  • Inline boxes flow with text, are only as wide as their content, and ignore width, height and top/bottom margin.
  • Inline-block flows inline but accepts width, height and padding on every side.
  • The display property is the switch; none, flex and grid come later.

That is the block versus inline distinction. With it in hand, the next step is the box model, where the width, height, padding and margin you just met are defined precisely.