auto margins in flex are a feature, not a bug

· Tags: flexbox, layout

The classic header layout: logo on the left, navigation on the right, vertical centring throughout. The shortest correct flexbox solution is two lines: display: flex; align-items: center on the parent, and margin-left: auto on the nav. No spacers, no justify-content: space-between, no extra wrappers.

How it works

Per Flexbox spec section 8.1, after the flex sizing algorithm has assigned space to items, any remaining free space along an axis is distributed equally to that axis’s auto margins before justify-content or align-self get to act. Set one auto margin and it absorbs everything; set two and they split it. justify-content only sees free space if there are no auto margins on that axis.

This is the same rule that makes margin: 0 auto centre a block element — auto margins absorb available space — extended to both axes and to the cross axis as well.

The patterns

  • Push one item: margin-left: auto on the item that should sit at the end. Everything before it stays grouped.
  • Centre one item across both axes: margin: auto on the item, regardless of justify-content or align-items on the container.
  • Split into two groups: a single margin-left: auto on the first member of the second group is cleaner than wrapping the groups in two divs and using space-between.
  • Sticky footer pattern: a column flex with margin-top: auto on the footer pushes it to the bottom.

Why this beats space-between

justify-content: space-between needs at least two items and distributes gaps based on count. Auto margins do not care about siblings — you can have one item, three items, or a varying number, and the alignment behaviour is stable. CSS-Tricks documented the trick early in “Aligning Things in CSS” (Rachel Andrew, 2017), and it has not aged.

The cross-axis case

Auto margins work on the cross axis too. margin-top: auto on a single flex item in a row layout pushes it to the bottom of the line. This overrides align-self, which is occasionally what you want when one item should drift to the bottom while the rest centre.

Caveat

Auto margins consume free space, so an item with margin: auto in a fully-packed flex container has no auto margin to apply. If items already fill the container along an axis, auto margins on that axis behave as zero. Add flex: 0 0 auto to your items if you need a guarantee.

Related

Get FlexFrog on the App Store. Built by Moruk Labs.