skip to content

In a browser's rendering pipeline, what does the layout stage (reflow) actually compute, and which kinds of changes to a page invalidate it?

level: middleimportance: must knowfreq 68%

answer

  1. geometry, not colors
  2. used size and position per box
  3. percentages and auto resolve here
  4. fonts and images arriving late
  5. a scrollbar changes the viewport

basics

~20 s

Layout computes the used size and position of every box in the render tree. It is invalidated by DOM structure changes, geometric style changes, edited text, viewport resizes, and late-arriving fonts or images that change how much space content needs.

solid answer

~50 s

Layout, or reflow, is the stage that turns computed styles into geometry: for every box it resolves a used width and height and an exact position, breaks text into line boxes, and records scrollable overflow. Anything that can change that geometry dirties it. In practice that means DOM insertions, removals and moves; changes to geometric properties such as `width`, `padding`, `margin`, `border-width`, `font-size`, `line-height`, `display` or `position`; changing text content; a viewport resize or zoom; a web font finishing loading and replacing fallback glyph metrics; an image arriving whose intrinsic size was not reserved; and a scrollbar appearing or disappearing. Changes that cannot affect geometry — `color`, `background-color`, `visibility` — skip layout and go straight to paint. Layout is also the stage the browser can do incrementally: only boxes marked dirty and those whose geometry depends on them are recomputed.

code

html · 6 lines
html
<!-- No reserved space: layout runs again when the bytes arrive -->
<img src="hero.jpg" alt="">

<!-- Space reserved during first layout -->
<img src="hero.jpg" alt="" width="800" height="450">
<img src="hero.jpg" alt="" style="aspect-ratio: 16 / 9; width: 100%">

go deeper

for a junior

Be able to say that layout is where the browser works out how big each box is and where it goes, and to name obvious triggers: adding elements, changing width or padding, resizing the window.

for a middle

Explain that layout resolves computed values into used values — percentages, auto sizes and line breaking — and separate geometry-changing properties from paint-only ones. Mention that style writes batch into one pass rather than laying out per line.

for a senior

Bring in the triggers that arrive from outside the code: font swaps, unsized images, scrollbar appearance, viewport changes. Show you reserve space up front so late-arriving resources do not force a second layout and move content under the user.

for a principal

Frame it as a contract for the codebase: which components are allowed to change geometry at runtime, what every media element must declare so space is reserved, and how the font loading strategy is chosen so the layout consequences are decided once rather than per team.

## What layout produces Style resolution gives each element *computed* values, many of which are not yet numbers you can draw with: `width: 50%`, `height: auto`, `margin: auto`, `flex: 1`. Layout is the stage that resolves them into **used values** — a concrete size and position for every box in the render tree — by walking that tree with the containing block's dimensions in hand. Concretely, layout produces: - a used width and height for each box, including resolving percentages against the containing block and resolving intrinsic sizing where the size comes from the content; - a position for each box, in the coordinate space of its containing block; - **line boxes**: text is broken into lines using the font's glyph metrics, so line count and therefore block height fall out of layout; - **scrollable overflow**, which determines whether a scroll container has anything to scroll. This is the stage everyone calls reflow. Its cost is roughly proportional to the number of boxes it has to visit, not to the number of properties you changed — which is why one badly scoped change can be far more expensive than several well-scoped ones. ## What dirties it **Structural DOM changes.** Inserting, removing or moving an element changes what has to be placed and usually shifts everything after it in flow. **Geometric style changes.** Anything that participates in sizing or positioning: `width`, `height`, `min-`/`max-` variants, `padding`, `margin`, `border-width`, `display`, `position`, `float`, `top`/`left`/`right`/`bottom` on positioned boxes, `flex` and grid track properties, and text metrics such as `font-family`, `font-size`, `font-weight`, `line-height` and `letter-spacing`. **Content changes.** Setting `textContent`, editing a text node, or an input's value growing — all change how much space content needs. **Environment changes that come from outside your code**, and these are the ones people forget: - A **window resize**, device rotation or browser zoom changes the initial containing block, so the whole document is laid out again. - A **web font finishing loading** swaps in different glyph metrics; every line box using it is recomputed, which is the mechanism behind the visible text shift on a slow connection. - An **image or iframe arriving** whose intrinsic size was not reserved. Give an `<img>` `width` and `height` attributes, or an `aspect-ratio`, and the browser can reserve the right box during first layout instead of relaying out when the bytes land. - A **scrollbar appearing** because content grew past the container: on the root scroller this narrows the viewport and everything sized against it must be recomputed. ## What does not dirty it A computed-style change only reaches layout if it could change geometry. `color`, `background-color`, `border-color`, `box-shadow`, `border-radius`, `outline` and `visibility` do not: the boxes keep their sizes and positions, so the browser can skip straight to painting the affected area. This is the useful half of the pipeline mental model — knowing which stage a property first touches tells you what a change costs. ```js el.style.backgroundColor = 'red'; // paint only el.style.padding = '20px'; // layout, then paint ``` ## Layout is incremental Browsers do not lay out the whole document on every change. Each change marks the affected boxes dirty and propagates that mark up the ancestor chain, and at the next rendering opportunity the engine lays out from the highest dirty box down. Ordinary application code therefore never triggers layout directly by writing a style — it queues invalidation, and the engine does the work later, once, for everything that accumulated. That batching is the whole reason layout is affordable at all: hundreds of style writes in one turn produce one layout pass, not hundreds. It also means the interesting engineering question is not *whether* you caused a reflow, but *how much of the document* your change forced the engine to revisit.

  • Why does text visibly shift when a web font finishes loading, and which property controls that behaviour?
    Line breaking is done with the metrics of the font actually in use. While the fallback is showing, lines break at fallback widths; when the web font arrives, the browser relayouts with the new metrics and content moves. `font-display` controls the swap policy, and matching the fallback's metrics with `size-adjust` and the `ascent-override` family narrows how far things move.
  • Does setting an element's `style.width` in JavaScript cause layout to run immediately at that line?
    No. The write marks boxes dirty and the engine performs layout later, at the next rendering opportunity, folding every pending change into a single pass. That is why a loop of style writes costs one layout rather than one per iteration.
  • Why is changing `background-color` cheaper than changing `padding`?
    `background-color` cannot change any box's size or position, so the engine keeps the existing geometry and only repaints the affected area. `padding` changes the box's used dimensions, which can move its contents and everything after it in flow, so layout has to run before paint can.

saying these in an interview costs you the question

  • Says every style change triggers a reflow
  • Thinks layout resolves colors and shadows too
  • Believes each JavaScript style write lays out immediately
  • Ignores fonts and images as layout triggers
  • Confuses layout with painting the pixels

context