Skip to content

CSS Flexbox

CSS Flexbox is a one-dimensional layout system. It arranges items in a row or column and makes alignment, spacing, and flexible sizing easier.

.container {
display: flex;
}

The element with display: flex is the flex container. Its direct children become flex items.

Main axis and cross axis

Flexbox works along two axes:

  • The main axis follows flex-direction.
  • The cross axis runs perpendicular to the main axis.

With the default flex-direction: row, the main axis is horizontal and the cross axis is vertical.

Flex direction

flex-direction controls the direction in which items are placed.

.container {
display: flex;
flex-direction: row;
}

Available values are:

ValueBehavior
rowPlaces items along the inline direction.
row-reverseReverses the row visually.
columnPlaces items from top to bottom in horizontal writing.
column-reverseReverses the column visually.

Reversing items only changes their visual order. Keyboard and screen-reader order still follows the HTML, so keep the DOM order logical.

Justify content

justify-content aligns and distributes items along the main axis.

.navigation {
display: flex;
justify-content: space-between;
}

Common values include flex-start, center, flex-end, space-between, space-around, and space-evenly.

.actions {
display: flex;
justify-content: center;
gap: 1rem;
}

Align items

align-items controls the alignment of items along the cross axis.

.navigation {
display: flex;
align-items: center;
}

Useful values include stretch, flex-start, center, flex-end, and baseline.

stretch is the default. It stretches auto-sized items across the container’s cross axis.

Gap

The gap property adds consistent space between flex items without adding unwanted space around the container edges.

.button-group {
display: flex;
gap: 0.75rem;
}

You can define row and column gaps separately:

.tags {
row-gap: 0.5rem;
column-gap: 1rem;
}

Wrapping items

Flex items stay on one line by default and may shrink to fit. Enable wrapping when items should move onto additional lines.

.tags {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}

The flex-flow shorthand combines direction and wrapping:

.cards {
display: flex;
flex-flow: row wrap;
}

Align content

align-content distributes multiple flex lines along the cross axis. It only has a visible effect when wrapping creates extra lines and the container has extra cross-axis space.

.gallery {
display: flex;
flex-wrap: wrap;
align-content: space-between;
min-height: 30rem;
}

For alignment within a single line, use align-items instead.

Flex grow

flex-grow controls how an item uses available space. The default value is 0.

.main-content {
flex-grow: 1;
}

If multiple items grow, their values define a ratio:

.primary {
flex-grow: 2;
}
.secondary {
flex-grow: 1;
}

The primary item receives twice as much of the remaining space as the secondary item.

Flex shrink

flex-shrink controls how an item becomes smaller when there is not enough space. Its default value is 1.

.logo {
flex-shrink: 0;
}

Disabling shrinking can cause overflow, so use it only when an item must preserve its size.

Flex basis

flex-basis sets an item’s initial main-axis size before free space is distributed.

.sidebar {
flex-basis: 18rem;
}

In a row, it behaves similarly to an initial width. In a column, it behaves similarly to an initial height.

Flex shorthand

The flex shorthand combines grow, shrink, and basis.

.content {
flex: 1 1 30rem;
}

This means:

  • flex-grow: 1
  • flex-shrink: 1
  • flex-basis: 30rem

Common patterns include:

.fluid-item {
flex: 1;
}
.fixed-item {
flex: 0 0 12rem;
}

Align self

align-self overrides align-items for one flex item.

.featured-card {
align-self: stretch;
}

Order

order changes the visual position of a flex item. All items have order: 0 by default.

.featured {
order: -1;
}

Centering with Flexbox

Flexbox can center content on both axes.

.empty-state {
display: flex;
min-height: 20rem;
align-items: center;
justify-content: center;
}

Responsive navigation example

<nav class="nav">
<a class="logo" href="/">Guide Docs</a>
<div class="nav-links">
<a href="/html">HTML</a>
<a href="/css">CSS</a>
<a href="/javascript">JavaScript</a>
</div>
</nav>
.nav {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
padding: 1rem;
}
.nav-links {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
@media (max-width: 40rem) {
.nav {
align-items: flex-start;
flex-direction: column;
}
}

Flexible card layout

.cards {
display: flex;
flex-wrap: wrap;
gap: 1.5rem;
}
.card {
flex: 1 1 16rem;
padding: 1.5rem;
border: 1px solid #cbd5e1;
border-radius: 0.75rem;
}

Each card starts with a basis of 16rem, can grow to fill available space, and wraps when the row becomes too narrow.

Common mistakes

  • Applying flex properties to an element that is not a direct child of the flex container.
  • Confusing the main axis with the horizontal axis after using flex-direction: column.
  • Using align-content when there is only one flex line.
  • Setting flex-shrink: 0 on many items and causing horizontal overflow.
  • Reordering content visually while leaving an illogical keyboard order.
  • Using margins between every item instead of the container’s gap property.

Key points

  • Flexbox arranges direct children along one main axis.
  • justify-content works on the main axis; align-items works on the cross axis.
  • gap creates consistent space between items.
  • flex-grow, flex-shrink, and flex-basis control flexible sizing.
  • Wrapping helps a flex layout adapt to limited space.
  • Preserve meaningful DOM order for accessibility.

Next topic

Continue with CSS Grid to learn how to create two-dimensional layouts with rows and columns.