Skip to content
academia.sh

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: none produces no box, visibility: hidden occupies space, opacity: 0 stays 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.

Start typing to search.

↑↓ Esc navigate · open · close