Lesson 11 / 26
Display Types
The behavioral differences between block, inline, and inline-block boxes; the distinction between outer and inner display type, and the three separate ways of hiding an element.
Contents
The previous two lessons computed a box’s dimensions, but what kind of box a box is was
never asked. Why does a paragraph occupy its own line while an emphasis element inside it
stays in the flow of the text? When both are given width: 200px, why does only one change?
The difference comes from the display property. This lesson compares the three basic types —
block, inline, and inline-block — across four criteria, and shows that hiding is a separate
matter.
Three Types, Four Criteria
// display-types.mjs — tabulates which properties the display value affects const TYPES = { "block": { ownLine: true, widthApplies: true, verticalMargin: true, whitespaceSensitive: false }, "inline": { ownLine: false, widthApplies: false, verticalMargin: false, whitespaceSensitive: true }, "inline-block": { ownLine: false, widthApplies: true, verticalMargin: true, whitespaceSensitive: true }, "none": { ownLine: false, widthApplies: false, verticalMargin: false, whitespaceSensitive: false }, }; const headers = ["display", "own line", "width/height", "vertical margin", "whitespace-sensitive"]; console.log(headers.map((h, i) => h.padEnd(i === 0 ? 14 : 16)).join("")); for (const [name, props] of Object.entries(TYPES)) { const yn = (v) => (v ? "yes" : "no").padEnd(16); console.log(name.padEnd(14) + yn(props.ownLine) + yn(props.widthApplies) + yn(props.verticalMargin) + yn(props.whitespaceSensitive)); } // inline boxes laid side by side: the whitespace character in between is also a box console.log("\n--- inline layout (whitespace character included) ---"); const pieces = [ { kind: "inline-block", width: 80 }, { kind: "space", width: 4 }, { kind: "inline-block", width: 80 }, { kind: "space", width: 4 }, { kind: "inline-block", width: 80 }, ]; let x = 0; for (const p of pieces) { console.log(`${String(x).padStart(4)} .. ${x + p.width} ${p.kind}`); x += p.width; } console.log(`total line width: ${x} (boxes: ${80 * 3}, spaces: ${x - 240})`);
display own line width/height vertical margin whitespace-sensitive block yes yes yes no inline no no no yes inline-block no yes yes yes none no no no no --- inline layout (whitespace character included) --- 0 .. 80 inline-block 80 .. 84 space 84 .. 164 inline-block 164 .. 168 space 168 .. 248 inline-block total line width: 248 (boxes: 240, spaces: 8)
The table gives the answer to the previous lesson’s questions.
A block box fills the containing box’s inline axis from end to end and pushes whatever
follows it onto a new line. width and height apply; margin on all four sides applies too.
A paragraph, a heading, a section, and a list are of this type.
An inline box stays in the flow of the text and occupies only as much space as its
content. width and height declarations have no effect at all; the box’s size comes
from its content. Vertical margin is also ignored. Emphasis, a link, an abbreviation, and a
general-purpose span are of this type.
One warning is needed: on an inline box, horizontal padding and border do apply, but the painted area does not grow the line height. When vertical padding is given to a link, the colored area grows, the distance between lines does not change, and areas can overlap.
An inline-block box sits between the two: from outside it behaves like inline — it does
not occupy its own line, it sits side by side with its neighbors — but from inside it is a
block box; width, height, and margin on all four sides apply.
The Whitespace Character Counts in Inline Layout
The second part of the output shows a commonly encountered problem. When three 80-unit inline-block boxes are placed side by side, the total line width came out not 240 but 248. The 8 units in between come from the whitespace characters between the boxes in the source text.
The reason is that inline layout is text layout. Line breaks and spaces in the source text are collapsed into a single space character, and that character also takes up space. Its width depends on the font; the 4 units here are an example value.
The result is that when three boxes are given width: 33.333%, they do not fit on one line —
once the spaces are added, the total exceeds a hundred percent. This is the fragile side of
building grid-like layouts with inline-block, and it disappears in the layout systems in the
next course; in those models, text nodes between boxes take no part in layout.
Outer and Inner Display Type
The display property does not say one thing, it says two.
The outer display type determines how the box behaves in its container: block or
inline.
The inner display type determines how the box lays out its children: flow,
flow-root, flex, grid, table.
In two-value notation, the two are given separately:
.nav { display: block flex; }
The old single-value notations are shorthand for this pair: the word block means
block flow, the word inline-block means inline flow-root, the word flex means
block flex. This distinction explains why the inline-block type is described as
“block from the inside, inline from the outside” — the word really is made of two parts.
The flow-root value also deserves mention: it makes the box an independent root that
completes the flow of its children within itself. What this is for is shown in the floating
elements lesson.
Changing the Type Does Not Change the Meaning
An element’s display type comes from the browser’s default stylesheet and can be changed with
a declaration. Writing li { display: inline; } lines up list items side by side.
Only the layout changes. The document’s meaning — that this is a list item — stays in place, and programs reading the document tree continue to see it as one. This is a direct consequence of the structure-presentation distinction built in the Web Fundamentals and HTML course: making a heading inline does not stop it from being a heading.
The reverse is also true, and it carries a warning: making an element visually resemble
something else does not make it that thing. Giving a div element the appearance of a button
does not produce a button that can be focused and activated by keyboard. Appearance is style’s
job, behavior and meaning are markup’s.
Three Ways to Hide
display: none was the fourth row in the table, and it gave “no” on every criterion. The
reason is that this value produces no box. The element stays in the document tree but
takes no part in layout at all.
There are three separate ways to hide something, and their results differ:
| Notation | Produces a box | Occupies space | Visible to assistive technology |
|---|---|---|---|
display: none |
No | No | No |
visibility: hidden |
Yes | Yes | No |
opacity: 0 |
Yes | Yes | Yes |
The third row calls for attention: an element whose opacity is set to zero is invisible but is
still there — it can be focused, clicked, and read by a screen reader. Writing opacity: 0 to
hide something from the user does not remove it from the accessibility tree.
There is a fourth case as well: hiding text visually while leaving it for assistive
technology. This cannot be done with display: none; it is done with a rule set that clips
the element to a one-pixel area, and is usually named with a utility class like
.visually-hidden.
Types on the Station Page
/* station.css — step 10: display types */ .nav li { display: inline-block; margin-inline-end: 12px; } .measurement-table caption { display: table-caption; text-align: start; } .status-badge { display: inline-block; padding-block: 2px; padding-inline: 8px; border-radius: 4px; } .visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
The .status-badge class is defined as inline-block because it wants two things at once:
staying in the flow of the text and being able to take vertical padding. If it were inline,
the padding would be painted but would not grow the line height; if it were block, it would
drop to its own line.
The .visually-hidden class carries out the fourth case above: a box is produced, clipped to a
one-pixel area, and it stays in the accessibility tree. It is used in the measurement table to
write a unit visually once in the column header and repeat it for assistive technology in
every cell.
Summary
- A block box fills its container’s inline axis and occupies its own line;
width,height, and margin on all four sides apply. - An inline box stays in the flow of the text;
width,height, and vertical margin do not apply, horizontal padding and border are painted but do not grow the line height. - An inline-block box is inline from the outside, block from the inside; it lines up side by side but takes size and spacing declarations.
- In inline layout, whitespace characters in the source text also take up space; this is why the total of boxes placed side by side comes out wider than expected.
- The three ways of hiding give different results:
display: noneproduces no box,visibility: hiddenoccupies space,opacity: 0stays in the accessibility tree and open to interaction.
Next Step
This lesson defined the type of boxes but did not go into detail on how they are laid out. Why do block boxes stack top to bottom, by what rule are inline boxes broken into lines, why is the margin between two block boxes not the sum of the two? The next lesson defines the rules of normal flow and computes margin collapsing with numbers.
To keep your progress and take notes, Log in
My notes
Log in to take notes.