Skip to main content
Modern CSS layout modes like Flexbox and Grid provide powerful tools for creating responsive, flexible layouts. Understanding their algorithms is essential for building a browser engine and optimizing layout performance.

Flexbox algorithm

Flexbox is a one-dimensional layout method for arranging items along a main axis with flexible sizing.
Flexbox excels at distributing space and aligning items within a container, even when their sizes are unknown or dynamic.

Main and cross axis

Flexbox layouts are oriented along two perpendicular axes:
The primary axis along which flex items are laid out. Direction is determined by flex-direction.
.container {
  display: flex;
  flex-direction: row; /* horizontal main axis */
}
Main axis properties:
  • justify-content - Aligns items along main axis
  • flex-grow - Controls growth along main axis
  • flex-shrink - Controls shrinking along main axis
  • flex-basis - Sets initial size along main axis

Flex direction

The flex-direction property establishes the main axis:

row

Main axis runs left to right (or right to left in RTL languages). Items are arranged horizontally.

row-reverse

Main axis runs right to left (or left to right in RTL languages). Items are arranged horizontally in reverse order.

column

Main axis runs top to bottom. Items are arranged vertically.

column-reverse

Main axis runs bottom to top. Items are arranged vertically in reverse order.

Flex basis

The flex-basis property sets the initial size of a flex item before space distribution:
1

Determine flex basis

Start with the value of flex-basis. If set to auto, use the item’s content size or explicit width/height.
2

Apply constraints

Respect min-width, max-width, min-height, and max-height constraints.
3

Calculate hypothetical size

This becomes the item’s hypothetical main size before flex grow/shrink is applied.
.item {
  flex-basis: 200px; /* Start at 200px before growing/shrinking */
}

.item-auto {
  flex-basis: auto; /* Use content size or explicit width */
}

.item-zero {
  flex-basis: 0; /* Start at 0, allowing flex-grow to control size */
}
Setting flex-basis: 0 with flex-grow: 1 distributes space based purely on the grow factor, ignoring content size.

Flex grow

The flex-grow property controls how flex items expand to fill available space:
1

Calculate free space

Determine remaining space after laying out all items at their flex-basis size.
2

Sum grow factors

Add up all flex-grow values of items in the container.
3

Distribute proportionally

Each item receives additional space proportional to its flex-grow value divided by the total.
4

Apply constraints

Respect min/max size constraints. If an item hits a constraint, distribute its unused space to other items.
.container {
  display: flex;
  width: 500px;
}

.item-1 {
  flex-basis: 100px;
  flex-grow: 1; /* Gets 1/3 of remaining 200px = 166.67px total */
}

.item-2 {
  flex-basis: 100px;
  flex-grow: 2; /* Gets 2/3 of remaining 200px = 233.33px total */
}

.item-3 {
  flex-basis: 100px;
  flex-grow: 0; /* Stays at 100px */
}

Flex shrink

The flex-shrink property controls how flex items shrink when the container is too small:
1

Calculate overflow

Determine how much the items overflow the container when laid out at flex-basis size.
2

Calculate scaled shrink factors

Multiply each item’s flex-shrink value by its flex-basis to get its scaled factor.
3

Distribute proportionally

Each item shrinks proportionally to its scaled shrink factor divided by the total.
4

Apply constraints

Respect min-size constraints. If an item hits a minimum, remove it from shrinking calculations.
.container {
  display: flex;
  width: 300px;
}

.item-1 {
  flex-basis: 200px;
  flex-shrink: 1; /* Shrinks by (1 * 200) / (1*200 + 2*200) = 1/3 */
}

.item-2 {
  flex-basis: 200px;
  flex-shrink: 2; /* Shrinks by (2 * 200) / (1*200 + 2*200) = 2/3 */
}
Unlike flex-grow, flex-shrink is weighted by the item’s flex-basis. Larger items shrink more in absolute terms.

Complete flexbox layout algorithm

The full flexbox layout algorithm follows these steps:
1

Generate flex items

Determine which children become flex items. Absolutely positioned children and text nodes are handled differently.
2

Determine flex direction

Establish main and cross axes based on flex-direction and writing mode.
3

Calculate flex-basis

Determine the hypothetical main size of each flex item based on flex-basis, content size, and constraints.
4

Collect items into lines

If flex-wrap is enabled, break items into multiple lines based on container size.
5

Resolve flexible lengths

Apply flex-grow or flex-shrink to distribute free space or absorb overflow.
6

Determine cross size

Calculate each item’s cross size based on content, align-items, and align-self.
7

Align items on main axis

Position items along the main axis using justify-content.
8

Align items on cross axis

Position items along the cross axis using align-items, align-self, and align-content.
The flexbox specification defines a precise algorithm with many edge cases. Production implementations must handle nested flex containers, baseline alignment, and interactions with other layout modes.

Grid algorithm

CSS Grid is a two-dimensional layout system that divides space into rows and columns.

Grid track sizing

Grid tracks (rows and columns) are sized using a sophisticated algorithm that handles fixed, flexible, and content-based sizing:
Tracks with explicit sizes in absolute units.
.grid {
  display: grid;
  grid-template-columns: 100px 200px 150px;
  grid-template-rows: 50px auto;
}

Track sizing algorithm

The grid track sizing algorithm resolves track sizes through multiple passes:
1

Initialize track sizes

Set each track’s base size and growth limit based on its sizing function.
2

Resolve intrinsic sizes

For content-based tracks, measure min-content and max-content sizes of items in the track.
3

Maximize tracks

Distribute space to grow tracks up to their growth limits, starting with the smallest tracks.
4

Expand flexible tracks

If there are fr units, distribute remaining space proportionally to their flex factors.
5

Stretch auto tracks

If space remains and align-content or justify-content allow, grow auto tracks to fill the container.
Grid track sizing can be computationally expensive, especially with spanning items and complex sizing functions. Production engines use caching and incremental updates.

Grid item placement

Items are placed into the grid using automatic or explicit positioning:
Use line numbers or named lines to position items.
.item {
  grid-column: 2 / 4; /* Start at line 2, end at line 4 */
  grid-row: 1 / 3;
}

Item spanning

Grid items can span multiple rows or columns:
1

Parse span notation

Items can specify spans using the span keyword or explicit line numbers.
.item {
  grid-column: span 2; /* Span 2 columns */
  grid-row: 1 / span 3; /* Start at row 1, span 3 rows */
}
2

Resolve auto-placement

For auto-placed spanning items, find the first position where the item fits without overlapping.
3

Handle conflicts

If multiple items occupy the same cells, later items are placed in the next available space.

Grid gaps

The gap property (formerly grid-gap) adds spacing between tracks:
.grid {
  display: grid;
  gap: 20px; /* 20px gap between all rows and columns */
  /* or */
  row-gap: 20px;
  column-gap: 10px;
}
Gaps are added between tracks, not at the edges. A grid with 3 columns and a 10px gap has 2 gaps totaling 20px.

Implementation considerations

When implementing flexbox and grid algorithms:

Measure content sizes

Efficiently measure min-content and max-content sizes by performing layout with different constraints.

Handle circular dependencies

Detect and resolve circular dependencies where item size depends on container size which depends on item size.

Optimize for common cases

Fast-path simple layouts (all fixed sizes, no spanning) before running the full algorithm.

Cache intermediate results

Store track sizes and item placements to avoid recalculation when only some items change.
Performance consideration: Grid layout with many spanning items and intrinsic sizing can require multiple layout passes. Consider using fixed sizes or explicit placement where possible for better performance.
Project checkpoint: Implement flexbox and grid layout algorithms in your browser engine. Handle all flex properties (basis, grow, shrink) and grid features (track sizing, placement, spanning). Test with complex real-world layouts and measure algorithm performance.

Build docs developers (and LLMs) love