How Do Justify-Content and Align-Items Work in Flexbox?

In CSS Flexbox, justify-content and align-items are the primary container properties used to align elements and distribute unused space. The fundamental distinction between them depends on the flex container's direction: justify-content controls alignment along the main axis, while align-items controls alignment along the perpendicular cross axis. Understanding how these axes operate makes managing element spacing, positioning, and responsive adjustments straightforward.

Understanding Flexbox Axes

Flexbox positions items across two directional axes defined by the flex-direction property:

  • Main Axis: The default flow direction of flex items (flex-direction: row runs horizontally left-to-right, while flex-direction: column runs vertically top-to-bottom).
  • Cross Axis: The axis perpendicular to the main axis (vertical when flex-direction is row, and horizontal when flex-direction is column).

Because these axes switch depending on flex-direction, justify-content always dictates the primary flow direction, and align-items manages alignment across the secondary direction.

Distributing Space with justify-content

The justify-content property manages how leftover space along the main axis is allocated among and around flex items.

Common Values for justify-content

  • flex-start (Default): Items pack tightly toward the start of the main axis. Extra space sits at the end.
  • flex-end: Items pack tightly toward the end of the main axis. Extra space sits at the beginning.
  • center: Items cluster together in the exact middle of the main axis, sharing extra space evenly on both sides.
  • space-between: The first item touches the start edge, the last item touches the end edge, and remaining space is divided equally between adjacent items.
  • space-around: Extra space is distributed equally on both sides of each item. This leaves visual gaps between items that are twice the width of the outer edge gaps.
  • space-evenly: Extra space is distributed such that the gap between any two items and the gap from an item to the container edge are identical.
.flex-container {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
}

Aligning Items with align-items

The align-items property controls how flex items sit and stretch along the cross axis. Unlike justify-content, which primarily distributes spare space across gaps, align-items directly influences item positioning and dimension within the current line.

Common Values for align-items

  • stretch (Default): Items expand to fill the entire cross-axis dimension of the container, provided they do not have explicit cross-axis dimensions (height in rows, width in columns).
  • flex-start: Items align to the starting edge of the cross axis (top in a row container, left in a column container).
  • flex-end: Items align to the ending edge of the cross axis (bottom in a row container, right in a column container).
  • center: Items center vertically (in row layouts) or horizontally (in column layouts) along the cross axis.
  • baseline: Items align along their baseline text content, ensuring typography across varying font sizes aligns consistently.
.flex-container {
  display: flex;
  flex-direction: row;
  align-items: center;
}

Side-by-Side Comparison

Feature justify-content align-items
Target Axis Main axis Cross axis
Default Value flex-start stretch
Primary Role Distributes remaining space along the primary flow Aligns items and controls stretch across the secondary flow
**Behavior in row** Manages horizontal spacing Manages vertical alignment
**Behavior in column** Manages vertical spacing Manages horizontal alignment

Perfect Centering Example

Combining both properties allows for centering content both vertically and horizontally in just a few declarations:

.center-box {
  display: flex;
  justify-content: center; /* Centers along the main axis */
  align-items: center;     /* Centers along the cross axis */
  height: 100vh;
}

This combination distributes all available main-axis and cross-axis space evenly around the child elements, locking them into the center of the viewport or container.