Flexbox

On this page 7

Flexbox, formally the CSS Flexible Box Layout Module, is a one-dimensional layout model in CSS that arranges child elements along a single axis, either a row or a column, and distributes available space between them. It is activated by setting display: flex or display: inline-flex on a container, which turns its direct children into flex items.

Flexbox solved layout problems that were awkward with floats and inline blocks, such as vertical centering, equal-height items and flexible spacing. It is now supported in all modern browsers and is the standard tool for components such as navigation bars, toolbars, card footers and form rows.

How flexbox distributes space

Flexbox works with two axes. The main axis follows the direction set by flex-direction, and the cross axis runs perpendicular to it. All alignment and sizing properties refer to these axes rather than to fixed horizontal or vertical directions, which also makes flexbox adapt to right-to-left and vertical writing modes.

The layout algorithm first determines each item’s flex basis, its starting size along the main axis. It then compares the sum of the bases with the container size. Positive free space is shared according to flex-grow; negative free space, meaning overflow, is removed according to flex-shrink weighted by each item’s basis.

PropertyInitial valueWhat it controls
flex-grow0Share of positive free space the item receives
flex-shrink1How strongly the item shrinks when space is short
flex-basisautoStarting size before free space is distributed
The three flex item sizing properties

The shorthand flex combines all three. The keyword `flex: 1` means grow 1, shrink 1, basis 0%, which gives items equal widths regardless of content, while flex: auto uses the content size as the basis and therefore produces unequal widths for unequal content.

Container and item properties

Flexbox properties are split between the flex container and the flex items. Container properties define direction, wrapping and group alignment, while item properties adjust individual items.

PropertyCommon valuesEffect
flex-directionrow, column, row-reverseSets the main axis
flex-wrapnowrap, wrapAllows items to form multiple lines
justify-contentflex-start, center, space-betweenDistributes items along the main axis
align-itemsstretch, center, baselineAligns items on the cross axis
align-contentflex-start, space-betweenDistributes lines when wrapping
gapLength such as 1remSets consistent space between items
Key flex container properties

On the item side, align-self overrides cross-axis alignment for one item and order changes the visual position. Auto margins are also powerful: `margin-left: auto` pushes an item to the far end of a row, a common technique for placing a login button at the right of a navigation bar.

Flexbox compared with CSS grid

Flexbox and CSS grid are complementary, not competing. Flexbox is content-out: items determine their size and the container adapts. Grid is layout-in: the container defines tracks and items are placed into them.

CriterionFlexboxCSS grid
DimensionsOne axis at a timeRows and columns together
Sizing driverItem contentContainer track definitions
Alignment across linesEach wrapped line is independentItems align to shared tracks
Typical useToolbars, nav bars, button groupsPage layouts, card galleries, dashboards
Overlapping itemsNot supported directlySupported by placing items in the same cells
Choosing between flexbox and CSS grid

A practical rule is to use grid when items must line up in two directions and flexbox when a group of items only needs to flow and align in one direction. Both are often combined, with a grid for the page and flexbox inside its components, and container queries can adjust either one based on the component’s own width.

Typical flexbox patterns

A small set of patterns covers most everyday uses of flexbox in production code.

PatternKey declarationsResult
Perfect centeringjustify-content and align-items set to centerChild centered on both axes
Navigation baralign-items center, gap, auto marginLinks aligned with an item pushed to the end
Equal columnsflex: 1 on each itemColumns share width equally
Sticky footerColumn direction, flex-grow on main contentFooter stays at the bottom of short pages
Wrapping tagsflex-wrap: wrap with gapItems flow onto new lines as needed
Common layout patterns

Pitfalls and common mistakes

Most flexbox problems come from default values that are not obvious. Knowing them prevents a large share of layout bugs.

  • Minimum size auto: flex items will not shrink below their content width by default, so long words or wide tables overflow; setting min-width: 0 fixes this.
  • Visual reordering: order and reverse directions change only the visual sequence, not the reading or tab order, which can confuse keyboard and screen reader users.
  • Grid-like expectations: wrapped flex lines do not align columns across lines; use CSS grid for true columns.
  • Margins between items: the gap property is cleaner than margins and avoids extra space at the edges.
  • Percentage heights in columns: children may not resolve heights as expected unless the container has a definite height.

The minimum size issue is the single most frequent surprise. When text refuses to truncate with an ellipsis inside a flex item, the cause is almost always the automatic minimum width.

A plain-language summary

Flexbox is a way of telling a web browser how to line up a group of elements. They can sit in a row or in a column. Flexbox also decides how the free space is shared between them.

Imagine books on a shelf that can stretch or shrink. You decide whether they sit close together, spread out or stand in the middle. The shelf then adjusts by itself when it gets wider or narrower, for example on a phone screen.

An example from practice

A front-end developer builds the header of an online shop. It contains a logo, a search field, three navigation links and a cart button, and it must work from 320 px phone screens to wide desktop monitors.

The header becomes a flex container with align-items: center and a gap of 1rem. The search field gets flex: 1 so it takes the remaining space, and min-width: 0 lets it shrink on small screens. The cart button receives margin-left: auto to stay at the right edge.

On narrow screens, a media query switches on wrapping so the search field moves to its own line. The result is a header that adapts without fixed widths and needs only a few lines of CSS.