One of the most frequent CSS layout questions is:

Explain how Flexbox works under the hood. How do flex-grow, flex-shrink, and flex-basis interact to determine the final size of a flex item? Provide the step-by-step arithmetic.

Flexbox (Flexible Box Layout) is a one-dimensional layout model designed to distribute space along a single axis (either horizontally or vertically) and align items dynamically inside a container, even when their sizes are unknown or dynamic.

To answer this comprehensively, you need to understand:

  1. Main Axis vs. Cross Axis: The spatial framework.
  2. Parent Container Properties: Layout flow and wrapping.
  3. Flex Item Sizing (The Flex Trinity): Sizing mechanics (grow, shrink, basis).
  4. Calculations: Step-by-step math for flex growth and shrinkage.
  5. Common Layout Patterns: Practical frontend interview code problems.

1. Main Axis vs. Cross Axis#

Flexbox aligns items along two axes. The directions of these axes depend on the parent container's flex-direction property:

Flexbox Axes

  • Main Axis: The primary axis along which flex items are laid out. Sizing along this axis is governed by the items' flex properties and aligned using justify-content.
  • Cross Axis: The perpendicular axis to the main axis. Alignment along this axis is governed by align-items (on the container) and align-self (on individual items).

2. Parent Container Properties#

Set display: flex or display: inline-flex on the parent to create a flex context.

  • flex-direction: Sets the main axis (row [default], row-reverse, column, column-reverse).
  • flex-wrap: Toggles whether items wrap onto multiple lines if container space runs out (nowrap [default], wrap, wrap-reverse).
  • justify-content: Aligns items along the main axis (flex-start, flex-end, center, space-between, space-around, space-evenly).
  • align-items: Aligns items along the cross axis for the current row track (stretch [default], flex-start, flex-end, center, baseline).
  • align-content: Aligns multi-line flex rows along the cross axis when wrapping occurs (stretch, flex-start, flex-end, center, space-between, space-around).

3. Flex Item Sizing: The Flex Trinity#

Sizing on a flex child is controlled by three properties, often combined into the shorthand: flex: [flex-grow] [flex-shrink] [flex-basis].

A. flex-basis#

Defines the initial size of the flex item before any free space is distributed.

  • Default: auto (the browser looks at the item's width/height property or defaults to content size).
  • Can be set to explicit units (e.g. 200px, 20%) or 0 (which ignores the content width during space calculation).

B. flex-grow#

Defines the item's ability to grow if there is positive remaining space in the flex container.

  • Default: 0 (items will not grow to fill remaining space).
  • Values are unitless proportions (e.g., flex-grow: 2 will grow twice as much as flex-grow: 1).

C. flex-shrink#

Defines the item's ability to shrink if the container's space is smaller than the sum of all items' initial flex-basis values (preventing container overflow).

  • Default: 1 (items shrink proportionally to prevent overflow).
  • Setting flex-shrink: 0 prevents the item from shrinking below its initial content size, causing it to overflow the container if space is insufficient.

4. Space Distribution Calculations (The Arithmetic)#

A senior candidate is expected to explain exactly how browser layout engines calculate final dimensions under two scenarios: Positive Free Space (growing) and Negative Space (shrinking).

Scenario A: Growing (Positive Free Space)#

Suppose we have a container with a width of 500px containing two items:

  • Item A: flex-basis: 100px, flex-grow: 1
  • Item B: flex-basis: 200px, flex-grow: 2

Flexbox Sizing Math

Sizing Step-by-Step:

  1. Calculate Initial Space: Sum of items' basis = 100px + 200px = 300px.
  2. Calculate Remaining Free Space: Container Width - Initial Space = 500px - 300px = 200px.
  3. Calculate Growth Units: Total grow factors = 1 + 2 = 3.
  4. Distribute Space:
    • Item A gets: (1 / 3) * 200px = 66.67px. Final Width = 100px + 66.67px = 166.67px.
    • Item B gets: (2 / 3) * 200px = 133.33px. Final Width = 200px + 133.33px = 333.33px.

Scenario B: Shrinking (Negative Space / Overflow)#

Suppose we have a container with a width of 300px containing two items:

  • Item A: flex-basis: 100px, flex-shrink: 1
  • Item B: flex-basis: 300px, flex-shrink: 3

Since the sum of bases (400px) exceeds the container width (300px), the browser must shrink the items to fit, distributing 100px of negative space (overflow).

Sizing Step-by-Step:

Unlike grow calculations (which look only at grow ratios), shrink calculations multiply the shrink factor by the item's basis size to prevent larger elements from shrinking disproportionately fast.

  1. Calculate Weighted Shrink Total:
    • Weighted Total = Sum of (basis * shrink factor)
    • Weighted Total = (100px * 1) + (300px * 3) = 100 + 900 = 1000.
  2. Calculate Shrink Ratios:
    • Item A: (100 * 1) / 1000 = 10% of total shrink weight.
    • Item B: (300 * 3) / 1000 = 90% of total shrink weight.
  3. Distribute Shrink Amount (100px Overflow):
    • Item A shrinks by: 10% * 100px = 10px. Final Width = 100px - 10px = 90px.
    • Item B shrinks by: 90% * 100px = 90px. Final Width = 300px - 90px = 210px.

5. Practical Interview Layout Exercises#

Exercise A: Vertical & Horizontal Centering#

A classic baseline layout test: center a box both horizontally and vertically inside a full-viewport container.

CSS
.viewport-centered-container {
  display: flex;
  justify-content: center; /* Centering along main axis (horizontal) */
  align-items: center;     /* Centering along cross axis (vertical) */
  min-height: 100vh;       /* Ensure container fills the viewport height */
}

Ensure a footer stays at the bottom of the viewport when content is short, but pushes down naturally if content grows.

HTML
<div class="page-container">
  <header>Header Content</header>
  <main class="page-body">Main Content Area</main>
  <footer>Footer Content</footer>
</div>
CSS
.page-container {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.page-body {
  flex-grow: 1; /* Automatically consumes all remaining vertical space, pushing footer down */
}

Key Takeaways#

  • One-Dimensional Design: Use Flexbox when aligning content items sequentially in a row or column (e.g., lists, buttons, small forms).
  • Axis Swap: If flex-direction changes, the main and cross axes swap roles instantly. Always keep track of what axis justify-content vs. align-items is targeting.
  • Sizing Priority: flex-basis sets the starting size. flex-grow handles extra positive container space. flex-shrink handles negative container overflow using weighted basis ratios.