Skip to content
academia.sh

Lesson 16 / 26

Overflow Management

Handling the case where content does not fit its box; comparing overflow values, the separate mechanisms for text overflow, and clipping's accessibility cost.

Contents

Throughout this topic, boxes were sized, arranged, and overlapped. One situation has not been addressed: what happens when content does not fit its box?

The situation is unavoidable. A long station name does not fit a narrow cell, a nine-column measurement table does not fit a narrow screen, a long caption does not fit a card given a fixed height. This lesson takes up what overflow is, what each of the options costs, and why text overflow is a separate matter.

Overflow’s Default Behavior Is Visibility

When a box’s content does not fit the box, the default behavior is for the content to spill out and stay visible. It is not clipped, not hidden, and does not grow the box.

This choice is deliberate: content that disappears is worse than content that breaks the layout. Overflowing text stays visible and readable; the problem is seen and can be fixed.

// overflow.mjs — computes whether content fits the box and the result of each overflow value
function overflowState({ boxWidth, boxHeight, contentWidth, contentHeight, overflow }) {
  const horizontal = Math.max(0, contentWidth - boxWidth);
  const vertical = Math.max(0, contentHeight - boxHeight);
  const result = {
    "visible": { visible: true,  scrollable: false, clips: false },
    "hidden":  { visible: false, scrollable: false, clips: true  },
    "clip":    { visible: false, scrollable: false, clips: true  },
    "scroll":  { visible: false, scrollable: true,  clips: true  },
    "auto":    { visible: false, scrollable: horizontal > 0 || vertical > 0, clips: true },
  }[overflow];
  return { horizontal, vertical, ...result };
}

const box = { boxWidth: 320, boxHeight: 120 };
const content = { contentWidth: 480, contentHeight: 200 };
console.log(`box ${box.boxWidth}x${box.boxHeight}, content ${content.contentWidth}x${content.contentHeight}`);
for (const value of ["visible", "hidden", "clip", "scroll", "auto"]) {
  const r = overflowState({ ...box, ...content, overflow: value });
  console.log(`${value.padEnd(8)} overflow=${r.horizontal}x${r.vertical}  visible from outside=${String(r.visible).padEnd(5)} scrollable=${String(r.scrollable).padEnd(5)} clips=${r.clips}`);
}

console.log("\n--- content that fits ---");
for (const value of ["scroll", "auto"]) {
  const r = overflowState({ ...box, contentWidth: 300, contentHeight: 100, overflow: value });
  console.log(`${value.padEnd(8)} overflow=${r.horizontal}x${r.vertical}  scrollable=${r.scrollable}`);
}

console.log("\n--- a long word fitting a line ---");
const word = "North-Slope-Automatic-Measurement-Station";
const CHAR_WIDTH = 8;   // an example font's character width
const boxWidth = 160;
const fits = Math.floor(boxWidth / CHAR_WIDTH);
console.log(`word ${word.length} characters x ${CHAR_WIDTH}px = ${word.length * CHAR_WIDTH}px`);
console.log(`box ${boxWidth}px -> ${fits} characters fit a line, overflow ${word.length * CHAR_WIDTH - boxWidth}px`);
const pieces = word.match(new RegExp(`.{1,${fits}}`, "g"));
console.log("split with overflow-wrap: anywhere:");
for (const p of pieces) console.log(`  |${p.padEnd(fits)}|`);
box 320x120, content 480x200
visible  overflow=160x80  visible from outside=true  scrollable=false clips=false
hidden   overflow=160x80  visible from outside=false scrollable=false clips=true
clip     overflow=160x80  visible from outside=false scrollable=false clips=true
scroll   overflow=160x80  visible from outside=false scrollable=true  clips=true
auto     overflow=160x80  visible from outside=false scrollable=true  clips=true

--- content that fits ---
scroll   overflow=0x0  scrollable=true
auto     overflow=0x0  scrollable=false

--- a long word fitting a line ---
word 41 characters x 8px = 328px
box 160px -> 20 characters fit a line, overflow 168px
split with overflow-wrap: anywhere:
  |North-Slope-Automati|
  |c-Measurement-Statio|
  |n                   |

Comparing the Five Values

visible — the initial value. Content overflows and stays visible. The box itself does not grow; its neighbors have no knowledge of the overflow and can be painted over it.

hidden — the overflowing part is clipped and becomes unreachable. No scrollbar is shown, but the box is still a box that can be scrolled programmatically; a focused element can be brought into the visible area.

clip — clips like hidden but does not make the box scrollable. The clipping is final.

scroll — the overflowing part is clipped and a scrollbar is always shown.

auto — clips and shows a scrollbar only when needed.

The output’s second block gives the difference between these last two values: when content fits the box, scroll still produces a scrollable box, auto does not. In some environments a scrollbar takes up space; writing scroll in this case reserves a strip and narrows the box even when content fits. If scrolling should appear only when needed, auto is written.

The Cost of Clipping

Writing overflow: hidden is a frequently reached-for fix, and it is used for two different purposes. The two need to be told apart.

The first use is deliberate clipping: fitting an image into a box, keeping a decorative shape from spilling out. What is clipped here carries no information.

The second use is making the overflow problem invisible: content does not fit, and hiding it pretends the problem has gone away. This does not solve the problem; it hides it from the user. Clipped text can still be read by a screen reader but is visually unreachable; a user navigating by keyboard can focus it but cannot see it.

The distinction is made with this question: is it acceptable for the clipped thing to be lost? If the answer is no, hidden is not written — auto is written instead, or the box’s size is made flexible.

There is one more side effect, and it has come up twice in earlier lessons: an overflow value other than visible makes the box an independent formatting root. Floated children are included in the height, margin collapsing stops at the box’s boundary. This is why writing overflow: hidden sometimes produces a layout change that looks unrelated.

Two Axes Separately

overflow is a shorthand; it sets the overflow-x and overflow-y longhands. Their logical counterparts are overflow-inline and overflow-block.

The two axes can be given different values, but there is a constraint: if one axis is visible while the other takes a clipping value, the visible axis is treated like auto. The two axes are not independent; a box that clips in one direction cannot leave overflowing content visible in the other.

Horizontal scrolling needs special handling. The way to show a wide measurement table on a narrow screen is to place the table inside a horizontally scrollable box. Such a box must also be reachable by keyboard; giving a scrollable region tabindex="0" and naming it with an accessible name is the counterpart of this.

Text Overflow Is a Separate Mechanism

The output’s third block points to a different problem. A forty-one-character word does not fit a 160-unit box and overflows by 168 units. This is not a problem to be solved with overflow — the word needs to be broken.

Line-breaking rules are managed by separate properties:

overflow-wrap: anywhere — breaks a word that does not fit at any point. The output’s last lines showed the break made under this rule. The break-word value does similar work but is not included in the box’s minimum content size calculation.

word-break: break-all — breaks words whether or not they fit; it pays no attention to word integrity.

hyphens: auto — hyphenates according to the document’s language and puts a hyphen at the break point. It requires the lang attribute to be declared; this is one more counterpart of the lang="en" declaration written on the root element in the Web Fundamentals and HTML course.

white-space: nowrap — does the opposite: prevents line breaking altogether. This does not prevent overflow, it guarantees it.

text-overflow: ellipsis — puts an ellipsis at the end of overflowing text. It does not work alone; the box must be clipping and must be a single line:

.station-name {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

The three declarations are written together. It must not be forgotten that the clipped text is lost: the full name should stay reachable in a title attribute or somewhere else.

/* station.css — step 15: overflow */
.table-wrapper {
  overflow-x: auto;
  overscroll-behavior-x: contain;
}

.measurement-table { min-width: 40rem; }

.card .description {
  overflow-wrap: anywhere;
  hyphens: auto;
}

.location-image img { overflow: clip; }

.table-wrapper makes the table horizontally scrollable on a narrow screen; the min-width declaration keeps the table from being squeezed into unreadability. Together, the two choose to scroll the table rather than shrink it.

overscroll-behavior-x: contain keeps the page from shifting once the box’s own scrolling ends — it keeps the scroll chain stopping at that box.

Summary

  • Overflow’s default behavior is visibility: content spills outside the box and stays readable. This rests on the assumption that lost content is worse than a broken layout.
  • hidden and clip clip; scroll always shows a scrollbar, auto shows one only when needed; when content fits, scroll still produces a scrollable box.
  • An overflow value other than visible makes the box an independent formatting root; it contains floated children and stops margin collapsing at its boundary.
  • The two axes are not independent: while one axis clips, the other cannot stay visible, and is treated like auto.
  • A word that does not fit is solved not with overflow but with line-breaking properties; text-overflow: ellipsis does not work alone, it is written together with clipping and single-line declarations.

Next Step

This topic built the size, arrangement, and boundaries of boxes. The page that results is structured but colorless: every decision so far concerned geometry. The next topic takes up visual properties, and the first question is color itself — how a color is written, in which space it is defined, and how the contrast between two colors turns into a number.

To keep your progress and take notes, Log in

My notes

Log in to take notes.

Start typing to search.

↑↓ Esc navigate · open · close