Question

CSS align-items vs align-content: Key Differences Explained

csslayoutflexboxalignment

Question

What is the difference between the CSS properties align-items and align-content? In particular, how does each property affect the layout of items in Flexbox and CSS Grid?

Short Answer

You will learn that align-items positions individual items within their own row, column, or grid area, while align-content positions or distributes groups of lines/tracks when extra space exists in the container. You will also see why align-content often appears to have no effect.

Concept

align-items and align-content both work on the cross axis, but they control different things.

  • align-items aligns the items inside their available space.
  • align-content aligns or distributes the entire set of flex lines or grid tracks inside the container.

In a Flexbox row (flex-direction: row), the main axis is horizontal and the cross axis is vertical. Therefore, align-items usually controls vertical alignment of the flex items.

align-content becomes useful only when the container has:

  1. More than one flex line, usually created with flex-wrap: wrap, or multiple grid tracks.
  2. Extra space on the cross axis.

For example, a wrapping flex container with a fixed height may have two rows of cards near the top and unused space below them. align-content decides whether those rows stay at the top, move to the center, spread apart, and so on.

In CSS Grid, align-items aligns content within each grid cell, while align-content aligns the grid as a whole within its container when the grid does not fill the container height.

Mental Model

Imagine a bookshelf.

  • Each book is an item.
  • Each shelf is a line of items.
  • The entire bookshelf has empty room above, below, or between shelves.

align-items decides where each book sits on its own shelf: at the top, middle, or bottom.

align-content decides where the shelves sit in the bookshelf: grouped at the top, centered together, or spread throughout the available height.

If there is only one shelf, moving the group of shelves usually makes no meaningful difference. That is why align-content commonly seems not to work in a single-line Flexbox layout.

Take Quiz

Syntax and Examples

In a Flexbox container with the default flex-direction: row, both properties use the vertical cross axis.

.container {
  display: flex;
  flex-wrap: wrap;
  height: 300px;

  align-items: center;
  align-content: space-between;
}
  • align-items: center centers each item within its own flex line.
  • align-content: space-between places the first and last flex lines at opposite ends of the container and distributes remaining lines between them.

align-items example

<div class="items-demo">
  <div class="short">Short</div>
  <div class="tall">Tall item</div>
  <div class="short">Short</div>
</div>
.items-demo {
  display: flex;
  align-items: center;
  height: 160px;
  gap: 12px;
  border: 2px solid #333;
}

.short,
.tall {
  padding: 12px;
  background: #cfe8ff;
}

.tall {
  padding-top: 40px;
  padding-bottom: 40px;
}

The three items have different heights. align-items: center vertically centers every item in the container's single flex line.

align-content example

<div class="content-demo">
  <div>1</div><div>2</div><div>3</div>
  <div>4</div><div>5</div><div>6</div>
</div>
.content-demo {
  display: flex;
  flex-wrap: wrap;
  align-content: space-around;
  width: 240px;
  height: 300px;
  gap: 8px;
  border: 2px solid #333;
}

.content-demo div {
  width: 70px;
  padding: 12px;
  background: #d8f5d0;
}

The items wrap into multiple rows. align-content: space-around distributes those rows vertically in the 300px-high container.

Step by Step Execution

Consider this Flexbox layout:

.container {
  display: flex;
  flex-wrap: wrap;
  width: 220px;
  height: 300px;
  align-items: center;
  align-content: space-between;
}

.item {
  width: 90px;
  height: 40px;
}

Assume there are four .item elements.

  1. display: flex turns .container into a flex container.
  2. The default direction is row, so items are placed from left to right.
  3. The width is only 220px. Two 90px items fit on each row, so four items form two flex lines.
  4. The container is 300px tall, but the two rows need much less vertical space. This leaves free space on the cross axis.
  5. align-content: space-between puts one flex line near the top and the other near the bottom, using the free vertical space between them.
  6. Within each row, align-items: center would center an item vertically if its cross-axis size differed from the line's size.

So align-content moves the rows, while align-items positions the items within a row.

Real World Use Cases

  • Card galleries: A responsive card layout wraps cards into rows. align-content can distribute rows within a fixed-height panel.
  • Dashboard widgets: Widgets with different heights can use align-items: stretch, center, or start to create a consistent visual layout.
  • Image and text controls: A button or navigation bar often uses align-items: center to vertically center icons and labels.
  • Grid-based admin screens: In CSS Grid, align-items controls how content sits within each cell, while align-content controls the grid's placement in a taller dashboard region.
  • Empty-state layouts: A container with a small group of rows can use align-content: center to center the whole group vertically.
Take Quiz

Real Codebase Usage

Developers usually reach for align-items far more often because many UI components are single-line flex layouts.

Center an icon and label in a button

.button {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

This ensures that the icon and text are vertically aligned even if their natural heights differ.

Keep cards equal-height in a row

.card-row {
  display: flex;
  align-items: stretch;
  gap: 1rem;
}

stretch is the default in many cases. It makes auto-sized items stretch across the cross axis, which can produce equal-height cards.

Center a wrapped collection of tags or cards

.tag-panel {
  display: flex;
  flex-wrap: wrap;
  align-content: center;
  min-height: 16rem;
  gap: 0.5rem;
}

This is appropriate only if the wrapped lines do not already occupy the panel's full height.

CSS Grid pattern

.profile-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-template-rows: repeat(2, 80px);
  height: 300px;
  align-items: center;
  align-content: center;
}

Here, align-items centers content in each grid cell. align-content centers the two-row grid inside the taller container.

Common Mistakes

Expecting align-content to work in a one-line flex container

/* Usually no visible effect */
.container {
  display: flex;
  height: 300px;
  align-content: center;
}

A non-wrapping flex container has one flex line. Use align-items: center to position items in that single line, or add flex-wrap: wrap when a multi-line layout is intended.

Forgetting that free space is required

.container {
  display: flex;
  flex-wrap: wrap;
  align-content: space-between;
}

If the container's height is determined entirely by its content, there is no extra vertical space to distribute. Give the container a meaningful height or min-height when the design requires it.

Using align-content to align one item

/* Incorrect property for centering one item in a flex row */
.container {
  display: flex;
  align-content: center;
}

Use align-items to align all items on the cross axis. Use align-self when only one item needs a different alignment.

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

.special-item {
  align-self: flex-end;
}

Confusing the cross axis with the main axis

With flex-direction: row, align-* properties usually affect vertical positioning. With flex-direction: column, they usually affect horizontal positioning.

.column {
  display: flex;
  flex-direction: column;
  align-items: center; /* Horizontal centering */
}

Forgetting that justify-content is different

justify-content works on the main axis, not the cross axis. In the default row direction, it positions items horizontally.

Comparisons

PropertyControlsFlexbox requirementTypical default-row effect
align-itemsIndividual items inside each lineWorks with one or many linesVertical alignment of items
align-contentThe group of flex lines or grid tracksNeeds multiple lines/tracks and free cross-axis spaceVertical distribution of rows
align-selfOne individual itemOverrides align-items for that itemChanges one item's vertical alignment
justify-contentItems or lines on the main axisFree main-axis space may be neededHorizontal distribution of items

Flexbox versus Grid

Layout systemalign-itemsalign-content
FlexboxAligns items within each flex lineDistributes multiple flex lines in the cross axis
GridAligns each item's content within its grid areaAligns the entire grid track collection in the container

Common values

Both properties commonly accept start, center, end, stretch, space-between, space-around, and space-evenly, although spacing values are most relevant to align-content. Browser support and exact behavior can depend on the layout mode and value used.

Take Quiz

Cheat Sheet

/* Align every item inside its own cross-axis space */
.container {
  display: flex;
  align-items: center;
}

/* Align one item differently */
.item {
  align-self: flex-end;
}

/* Distribute multiple wrapped lines in the cross axis */
.container {
  display: flex;
  flex-wrap: wrap;
  height: 300px;
  align-content: space-between;
}
  • align-items: aligns items.
  • align-content: aligns or distributes lines/tracks.
  • In flex-direction: row, the cross axis is usually vertical.
  • In flex-direction: column, the cross axis is usually horizontal.
  • align-content needs extra cross-axis space.
  • For Flexbox, align-content is most useful with flex-wrap: wrap and multiple lines.
  • Use justify-content for the main axis.

FAQ

Does align-content work without flex-wrap: wrap?

Usually, it has no visible effect in Flexbox because the container has only one flex line. It is intended to distribute multiple lines.

Why is align-content: center not centering my flex items?

It centers the group of flex lines, not individual items. For a single-row flex layout, use align-items: center for cross-axis centering.

What is the difference between align-items and align-self?

align-items sets the default cross-axis alignment for all children. align-self overrides that alignment for one child.

Is align-items vertical or horizontal?

It depends on flex-direction. It is vertical for the default row direction and horizontal for column.

Does align-content work in CSS Grid?

Yes. In Grid, it aligns the set of grid tracks inside the grid container when there is extra space on the block/cross axis.

When should I use justify-content instead?

Use it when you need alignment on the main axis: typically horizontal in a Flexbox row and vertical in a Flexbox column.

Take Quiz

Mini Project

Description

Build a small responsive card panel that wraps cards into rows. The project demonstrates the difference between centering the content of each card with align-items and distributing the card rows with align-content.

Goal

Create a wrapping Flexbox card panel where rows are spread vertically and each card centers its icon and label.

Requirements

  1. Create a flex container with six cards.
  2. Make the cards wrap into multiple rows on a narrow panel.
  3. Give the panel a fixed minimum height so extra vertical space exists.
  4. Use align-content to distribute the rows vertically.
  5. Use align-items to center the contents inside each card.
  6. Include an icon and text label in every card.
Take Quiz

Keep learning

Related questions

View more