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.
.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>.
These inline boxes sit on one line and wrap like words do.
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.)
.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:
- Put two
<span>elements next to each other and confirm they share one line. Now set both todisplay: blockand watch them stack. You just changed how they take up space. - Give a
<span>awidth: 300pxand aheight: 80pxand confirm both are ignored. Then adddisplay: inline-blockand watch the size finally take effect. - Build a row of four nav items using
display: inline-blockwith a fixedwidthand verticalpadding. 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
displayproperty is the switch;none,flexandgridcome 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.