Skip to main content
The layout engine is responsible for calculating the precise position and dimensions of every element on the page. This phase transforms the styled DOM tree into a geometric representation that can be painted to the screen.
Layout is one of the most computationally intensive phases in the browser rendering pipeline. Understanding how it works is crucial for building performant web applications.

Box model calculation

Every element in HTML is represented as a rectangular box. The box model defines how the size of each box is calculated based on content, padding, border, and margin.
1

Calculate content box

Determine the intrinsic size of the content, including text, images, and child elements.
2

Apply padding

Add padding space between the content and the border. Padding is included in the element’s background.
3

Apply border

Add border width around the padding area. Border styles and colors are applied during the paint phase.
4

Apply margin

Add margin space outside the border. Margins can collapse with adjacent elements’ margins.
The box-sizing property determines whether padding and border are included in the element’s specified width and height:
Default behavior. Width and height apply only to the content box. Padding and border are added outside.
total width = width + padding-left + padding-right + border-left + border-right

Normal flow

Normal flow is the default layout mode where elements are laid out according to their position in the document tree.

Block formatting context

Block-level elements stack vertically, each starting on a new line:
  • Each block takes up the full available width of its container
  • Blocks are positioned one after another vertically
  • Vertical margins between adjacent blocks collapse
  • Block elements establish their own formatting context

Inline formatting context

Inline elements flow horizontally within their containing block:
  • Inline elements sit on the same line as adjacent inline elements
  • Line breaking occurs when elements exceed container width
  • Vertical alignment is controlled by vertical-align
  • Inline elements respect horizontal margins and padding
Understanding the difference between block and inline formatting contexts is fundamental to predicting layout behavior.

Floats

Floats remove an element from normal flow and shift it to the left or right side of its container, allowing content to wrap around it.
1

Remove from normal flow

The floated element is taken out of the normal document flow, so block elements below it move up to fill the space.
2

Position to edge

The element is shifted to the left or right edge of its containing block, or until it touches another floated element.
3

Shrink to fit

Floated elements shrink-wrap to their content width unless an explicit width is set.
4

Wrap inline content

Subsequent inline content flows around the floated element, creating a wrapping effect.

Clearing floats

The clear property prevents an element from appearing next to floated elements:
  • clear: left - Element moves below left-floated elements
  • clear: right - Element moves below right-floated elements
  • clear: both - Element moves below all floated elements
Floats can cause parent containers to collapse to zero height if they only contain floated children. Use clearfix techniques or establish a new block formatting context to prevent this.

Positioning schemes

The position property determines how an element is positioned in the layout.
Default positioning. Element follows normal flow and ignores top, right, bottom, left, and z-index properties.
.element {
  position: static;
}

Stacking contexts

Positioned elements with a z-index value create stacking contexts that determine the painting order:
1

Establish stacking context

Elements with position other than static and a z-index value create a new stacking context.
2

Order children

Within a stacking context, children are ordered by their z-index value. Higher values appear on top.
3

Isolate from siblings

Elements within a stacking context cannot interleave with elements in a different stacking context.
Many properties beyond position and z-index can create stacking contexts, including opacity, transform, filter, and will-change.

Line breaking and text shaping

Text layout involves complex algorithms for breaking lines and shaping glyphs.

Line breaking algorithm

The browser determines where to break lines based on:
  • Available width in the container
  • Word boundaries and whitespace
  • Hyphenation rules (when enabled)
  • Breaking opportunities in the Unicode specification
  • Language-specific breaking rules
Lines break at whitespace and punctuation boundaries.
.text {
  word-break: normal;
  overflow-wrap: normal;
}

Text shaping

Text shaping converts character codes into positioned glyphs:
1

Font selection

Choose the appropriate font face based on font-family, font-weight, font-style, and character availability.
2

Glyph mapping

Map each character to its corresponding glyph in the selected font.
3

Apply OpenType features

Process ligatures, kerning, and other typographic features defined in the font.
4

Position glyphs

Calculate the exact position of each glyph based on metrics, kerning, and layout properties.
Text shaping is highly complex for languages with complex scripts (Arabic, Devanagari, Thai) that require contextual glyph selection and reordering.

Implementation considerations

When building a layout engine from scratch:

Incremental layout

Optimize by only recalculating layout for changed subtrees rather than the entire document.

Layout caching

Cache layout results to avoid redundant calculations when styles haven’t changed.

Constraint solving

Use efficient algorithms for resolving layout constraints, especially for complex layout modes.

Measurement phase

Separate measurement from positioning to enable more efficient layout passes.
Project checkpoint: Build a layout engine in C++ or Rust that handles box model calculation, normal flow, floats, and all positioning schemes. Test with real-world HTML documents and measure layout performance.

Build docs developers (and LLMs) love