CSS Flexbox: One-Dimensional Layout

Published Updated

CSS flexbox arranges a container's direct children along one main axis and aligns them along a cross axis. It handles navigation bars, button groups, card rows, form controls, and other layouts where content must share space in one direction.

Picture a shelf whose books can change width. The shelf is the flex container, and its direct children are flex items. Container rules choose the shelf direction and alignment. Item rules decide which books can grow, which can shrink, and the size each one starts from.

What Flexbox Controls

Setting display: flex creates a flex formatting context for the element's direct children. Text nested inside a child remains part of that child, and deeper descendants do not become flex items unless their own parent also uses flexbox.

The main axis always follows the current flex-direction value. With row, it normally runs in the inline direction. With column, it runs in the block direction. The cross axis always runs perpendicular to the main axis, so changing direction also changes the physical direction controlled by the alignment properties.

Flexbox resolves positive and negative free space. When room remains on the shelf, flex-grow decides how items share it. When the items need more room than the container offers, flex-shrink decides how the deficit is removed. flex-basis supplies the starting main size before either calculation.

Build a Flex Layout Step by Step

This sequence keeps one topic-card fixture and adds one flexbox decision at each step. Replace the earlier CSS block as you proceed so the rendered change stays visible.

<section class="topic-list">
  <article class="topic-card">Selectors</article>
  <article class="topic-card">Flexbox with a longer title</article>
  <article class="topic-card">Grid</article>
  <article class="topic-card">Positioning</article>
</section>

Turn on Flexbox

.topic-list {
  display: flex;
}

The section becomes a flex container after this declaration. Its four articles become flex items and move into a single row because the initial direction is row. The items keep content-based widths, and the browser allows them to shrink when the row runs short of space.

Choose the Flex Direction

.topic-list {
  display: flex;
  flex-direction: row;
}

The explicit row keeps the main axis running across the container. Change the value to column and each card stacks vertically because the main axis turns downward. The shelf has rotated, so later main-axis alignment rotates with it.

Justify and Align the Items

.topic-list {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: stretch;
}

justify-content: center groups the cards in the middle of the row when positive free space remains. align-items: stretch lets the cards fill the flex line's cross size, so cards with short labels can match the height of the card with a longer title.

If the direction changes to column, justification works vertically and alignment works horizontally. Property names describe the flex axes rather than fixed screen directions.

Add a Gap Between Items

.topic-list {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: stretch;
  gap: 1rem;
}

The items remain centered while one rem of space appears between each pair. A container gap does not add space at the outer edges, and it keeps spacing separate from a card's own margins. When cards wrap later, the same gap also separates the flex lines.

Allow Items to Wrap

.topic-list {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: stretch;
  gap: 1rem;
  flex-wrap: wrap;
}

flex-wrap: wrap permits items to move onto another line when they cannot fit. Each new line distributes its free space independently, which is a defining flexbox behavior. Cards in separate lines do not share column tracks, even when their widths happen to match.

Control Grow, Shrink, and Basis

.topic-list {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: stretch;
  gap: 1rem;
  flex-wrap: wrap;
}

.topic-card {
  flex: 1 1 14rem;
  min-width: 0;
}

The shorthand reads as flex-grow: 1, flex-shrink: 1, and flex-basis: 14rem. Each card starts from a preferred main size of 14rem. Cards on the same line grow to share leftover room, can shrink when necessary, and wrap once the container cannot fit another reasonable card.

The min-width: 0 declaration lets long content shrink below its automatic minimum width. On a narrow shelf, that rule prevents one long title or code sample from forcing the entire row beyond its container.

Common Pitfalls & Debugging

Alignment Follows the Current Axes

Symptom: justify-content: center moves items vertically when horizontal centering was expected. Cause: the container uses flex-direction: column, so the main axis is vertical. Fix: identify the current main axis, then use justify-content for that axis and align-items for the cross axis.

Items Overflow Because of Min-width

Symptom: a flex child pushes beyond the container even though shrinking is enabled. Cause: flex items default to an automatic minimum size, and long unbroken content can set a large min-content width. Fix: apply min-width: 0 to the shrinking flex item, then handle the content with wrapping or overflow rules appropriate to that content.

.main-panel {
  flex: 1 1 auto;
  min-width: 0;
}

.main-panel pre {
  overflow-x: auto;
}

The panel may now shrink within the row, while the code block scrolls internally if a line cannot wrap. Apply the minimum-size fix to the flex item that participates in sizing, which may be a wrapper around the visibly overflowing element.

Flex: 1 Uses a Zero Basis

Symptom: several items become equal widths even though their content sizes differ. Cause: browsers expand flex: 1 to a grow factor of one, a shrink factor of one, and a basis of 0%. Fix: use flex: 1 1 auto when content or an authored width should contribute to the starting size, or write an explicit basis such as 14rem.

When to Use Grid Instead

Flexbox treats each flex line as an independent shelf. That behavior fits controls and content-driven rows because one line can distribute space without coordinating with the next. It becomes awkward when items in several rows must keep the same column boundaries.

Use CSS grid when the layout needs shared row and column tracks, such as a dashboard or a gallery with aligned columns. A page can use grid for its outer structure and flexbox inside a toolbar, navigation region, or card header.

Conclusion

Start with the container's axes, then add alignment and wrapping before tuning item flexibility. When overflow appears, inspect the flex item's automatic minimum size before changing widths across the whole layout.

Frequently Asked Questions

What is the difference between justify-content and align-items?

justify-content distributes free space along the main axis. align-items positions items along the cross axis within the current flex line. Changing flex-direction changes which physical direction each axis follows.

Why do flex items shrink even when a width is set?

Flex items use flex-shrink: 1 by default, so the flex algorithm can reduce their main size when the container lacks space. Set an appropriate flex value, allow wrapping, or use flex-shrink: 0 only when the item must keep its declared size.

What does flex: 1 1 auto mean?

The item may grow with a factor of one, shrink with a factor of one, and start from its automatic main size. The automatic basis usually comes from the item's width or height, then from its content when that size is auto.

How do you centre an item both horizontally and vertically?

Set the container to display flex, then justify-content and align-items both to center. That centres on the main and cross axes at once, and it works whether the item is text, an image, or another container.

Sources

  1. [1]
    Basic concepts of flexbox
    (developer.mozilla.org)
  2. [2]
    justify-content
    (developer.mozilla.org)
  3. [3]
    align-items
    (developer.mozilla.org)
  4. [4]
  5. [5]
    flex-wrap
    (developer.mozilla.org)
  6. [6]
    min-width
    (developer.mozilla.org)