What display does
Every element has a display value that decides how it is laid out. The three you meet first are block, inline and inline-block. Here are three identical boxes, same width, height, padding and margin, only display differs:
block | inline | inline-block | |
|---|---|---|---|
| Starts on a new line | Yes | No | No |
| Width by default | Fills the container | Fits the content | Fits the content |
width and height | Apply | Ignored | Apply |
| Vertical margin | Applies | Ignored | Applies |
| Vertical padding | Pushes content | Painted, but does not push lines apart | Pushes content |
| Typical elements | div, p, h1, ul, section | span, a, strong, em | button, input, img (replaced elements behave like this) |
In the preview, the block box sits on its own line at 120px wide. The inline one ignores the width and height and wraps just its word, and its vertical padding and border stick out above and below the line without making the line any taller. The inline-block box stays in the line of text but keeps its full size.
display: block
A block element takes the whole available width and pushes whatever follows onto a new line. Turning a link into a block is how you make a whole row clickable:
.menu a {
display: block; /* the full row is the link */
padding: 10px 16px;
}
A block's width can be set, and margin: 0 auto centers it once it has one, as the center a div page shows.
display: inline-block
inline-block is the middle ground: it flows in a line like a word, but you can size it. It is useful for badges, buttons and icons inside text:
Several inline-block boxes in a row get a small gap between them from the whitespace in the HTML. For rows of boxes, display: flex on the parent is the better tool.
display: none vs visibility: hidden
Both make an element invisible. The difference is whether it keeps its space:
display: none | visibility: hidden | opacity: 0 | |
|---|---|---|---|
| Takes space | No | Yes | Yes |
| Can be clicked | No | No | Yes |
| Read by screen readers | No | No | Yes |
| Can be animated smoothly | No | No | Yes |
The HTML hidden attribute does the same as display: none through the browser's stylesheet, which means any CSS rule that sets display on the element (for example .card { display: flex; }) overrides it and the element shows again. Add [hidden] { display: none !important; } if that bites you.
To hide something visually but keep it for screen readers (a label for an icon button, say), use a "visually hidden" class instead of display: none.
display: flex and display: grid
These two turn an element into a layout container for its children:
display: flexlays children out in one row or column, with alignment and spacing control. See flexbox.display: gridplaces children on rows and columns at the same time.
The container itself stays a block. inline-flex and inline-grid do the same for the children but make the container flow inline, like inline-block.
The other values
| Value | What it does |
|---|---|
flow-root | A block that contains its floats and stops child margins leaking out; the modern "clearfix" |
contents | The element's own box disappears and its children act as children of its parent. Avoid on buttons, lists and tables: some browsers drop the element's meaning for screen readers |
list-item | A block with a list marker, the default for li |
table, table-row, table-cell | Table layout on non-table elements |
inline-flex, inline-grid | A flex or grid container that sits inline |
Common mistakes
- Setting
widthorheighton aspanora. Inline elements ignore them. Useinline-blockorblock. - Vertical margin on an inline element. Also ignored. Same fix.
- Using
display: noneto hide text meant for screen readers. It hides it from them too. - Expecting a child to show inside a
display: noneparent. Nothing inside a hidden parent renders. - A
displayrule overriding thehiddenattribute. The CSS rule wins. - Trying to animate
display. Settingdisplay: nonehides the element at once, with no fade; animateopacityand switchdisplay(orvisibility) at the end.
Frequently Asked Questions
What is the difference between block, inline and inline-block?
A block element starts on a new line and fills the available width. An inline element flows inside text and ignores width, height and vertical margins. inline-block flows inside text like inline but accepts width, height, padding and margins like a block.
What does display: none do?
It removes the element from the page completely: it takes no space, is not rendered, and is hidden from screen readers. Its children are hidden with it and cannot be shown with their own display value.
What is the difference between display: none and visibility: hidden?
display: none removes the element and its space. visibility: hidden makes it invisible but keeps its space in the layout, so nothing moves.
Is a div block or inline by default?
Block. div, p, headings, ul, section and form are block by default; span, a, strong, em, img, input and button are inline or inline-block.
Why do inline-block elements have a gap between them?
The whitespace between the tags in the HTML is rendered as a space, just like between words. Use display: flex with gap on the parent instead, or remove the whitespace.