Theme
On this page (11)

§One-dimensional composition

Start with flex or inline-flex - they only select the formatting context; direction, wrapping, alignment and spacing are added explicitly. stack is the convenience column with a default four-unit, density-aware gap. The classic toolbar: title on the start side, actions on the end side.

§A realistic toolbar

The same primitives compose a full application toolbar: identity on the start side, then search and actions on the end side. ms-auto is the flexible spacer - it absorbs the spare inline space and pushes everything after it to the end. When the page gets narrow the row wraps instead of overflowing.

§Distribution with justify-*

justify-* distributes items on the main axis. justify-between pins the edges, justify-around gives every item equal half-margins, justify-evenly equal full gaps. It distributes spare space - it is not a substitute for a minimum gap-*. Resize the demo with the toolbar to see the spare space come and go.

§Cross-axis alignment with items-* and self-*

items-* aligns the row's children on the cross axis; self-* overrides one child. items-baseline lines up text, self-stretch lets one panel fill the row's height.

§Flexible sizing: grow, shrink, basis

flex-1 lets an item grow and shrink from a zero basis - the fluid column. flex-none (shrink-0 + fixed size) pins an item - the icon, the thumbnail, the sidebar. grow / grow-0 and shrink / shrink-0 tune the factors individually; basis-0/auto/full sets the starting size. Resize the demo: the flex-1 columns absorb whatever the fixed w-24 box leaves.

§Wrapping rows of chips and cards

flex-wrap lets items flow onto new lines following the available width - tag lists, filter chips, card walls. flex-nowrap is the native default; keep it for toolbars that must never break. Resize the demo to watch the chips wrap and unwrap.

§Handle the real overflow source

A flex item's automatic minimum can resist shrinking. Apply min-w-0 to the flexible content region and choose text wrapping or scrolling - as in the label/content row of the first demo. Do not fix overflow by clipping the entire layout.

§Real world: a chat thread

A messaging panel is a stack of flex rows. Incoming rows pair a pinned avatar (size-8 shrink-0) with a fluid bubble (flex-1 min-w-0 p-3), bottom-aligned with items-end; the outgoing row flips to justify-end; the composer pins its button (shrink-0) against a fluid field (flex-1 min-w-0). The min-w-0 is what lets a bubble shrink below its content width - without it, a long unbroken word would stretch the row past the panel instead of wrapping. Resize with the toolbar: the avatars and the Send button hold their size while the bubbles and the field give.

§Available flex helpers

ConcernClasses
Directionflex-row, flex-col
Wrappingflex-wrap, flex-nowrap
Distributionjustify-start/end/center/between/around/evenly/normal
Cross-axis alignmentitems-start/end/center/baseline/stretch
Individual alignmentself-auto/start/end/center/baseline/stretch
Wrapped linescontent-start/end/center/between/around/evenly/stretch/normal
Flexibilityflex-1, flex-auto, flex-initial, flex-none
Growth / shrinkgrow, grow-0, shrink, shrink-0
Basisbasis-0, basis-auto, basis-full

§Change structure with a named query

<section class="query">
  <div class="flex flex-col gap-4 action-row">
    <button class="btn" type="button">First</button>
    <button class="btn" type="button">Second</button>
  </div>
</section>
@container layout (inline-size >= 30rem) {
  .action-row { flex-direction: row; }
}

The custom rule is unlayered, so it overrides the helper intentionally. No reverse-direction or order helpers are shipped: preserve the relationship between visual, reading and keyboard order.

§Platform references

CSS Flexible Box Layout · CSS cascade layers

Comments, ideas or improvements? Edit this page's source on GitHub