Question

Center Elements Horizontally and Vertically with CSS Flexbox

csshtmlflexbox

Question

How can I use CSS Flexbox to place numbered elements on separate rows and center each one horizontally within its container? I also want to understand how to center content vertically when the container has a defined height.

<div class="flex-container">
  <div class="row"><span class="flex-item">1</span></div>
  <div class="row"><span class="flex-item">2</span></div>
  <div class="row"><span class="flex-item">3</span></div>
  <div class="row"><span class="flex-item">4</span></div>
</div>
.flex-container {
  padding: 0;
  margin: 0;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: center;
}

.row {
  width: 100%;
}

.flex-item {
  background: tomato;
  padding: 5px;
  width: 200px;
  height: 150px;
  margin: 10px;
  line-height: 150px;
  color: white;
  font-weight: bold;
  font-size: 3em;
  text-align: center;
}

Short Answer

Flexbox centers flex items, not every nested element automatically. You will learn how the main and cross axes work, how flex-direction changes them, and how to stack items in rows while centering each row’s content.

Concept

A Flexbox layout has two important alignment directions:

  • The main axis is controlled by flex-direction.
  • The cross axis runs perpendicular to the main axis.

For the default direction, flex-direction: row:

  • Main axis: left to right
  • Cross axis: top to bottom
  • justify-content aligns items left-to-right.
  • align-items aligns items top-to-bottom.

Your .flex-container contains four .row elements, so those rows are the direct flex items. With the default row direction, Flexbox attempts to put all four rows beside one another.

To stack the rows vertically, set:

flex-direction: column;

Then each .row still needs its own Flexbox layout to center the .flex-item inside it horizontally. This matters because Flexbox alignment rules apply to a container's direct children. The outer container can align .row elements, while each .row aligns its own .flex-item.

For true vertical centering, the container must have extra vertical space, usually through height or min-height. If a container grows only as tall as its content, there is no unused vertical space in which to center anything.

Mental Model

Think of a Flexbox container as a shelf with two directions for arranging objects:

  • flex-direction decides whether the shelf runs across (row) or down (column).
  • justify-content moves objects along the shelf.
  • align-items moves objects across the shelf.

A nested Flexbox container is like putting a smaller shelf inside each compartment. The outer shelf positions the rows; each inner shelf positions the numbered box within its row.

Take Quiz

Syntax and Examples

The basic Flexbox centering pattern is:

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

With the default flex-direction: row, this centers direct children horizontally and vertically, provided the container has a height.

To stack direct children vertically and center them:

.container {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

For the numbered-row layout, use a nested Flexbox container:

<div class="flex-container">
  <div class="row"><div class="flex-item">1</div></div>
  <div class="row"><div class="flex-item">2</div></div>
  <div class="row"><div class="flex-item">3</div></div>
  <div class="row"><div class="flex-item">4</div></div>
</div>
.flex-container {
  display: flex;
  flex-direction: column;
}

.row {
  display: flex;
  justify-content: center;
  width: 100%;
}

.flex-item {
  width: 200px;
  height: 150px;
  margin: 10px;
  background: tomato;
  color: white;
  font-size: 3rem;
  font-weight: bold;

  display: flex;
  justify-content: center;
  align-items: center;
}

Each .row fills the available width. Its justify-content: center places its direct child, .flex-item, in the horizontal center.

Using a div for .flex-item is convenient because div is block-level. A span is inline by default, so its width and height do not apply as expected unless you set display: inline-block, block, or flex.

Step by Step Execution

Consider this layout:

.flex-container {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  justify-content: center;
}

.row {
  display: flex;
  justify-content: center;
}
<div class="flex-container">
  <div class="row"><div class="flex-item">1</div></div>
  <div class="row"><div class="flex-item">2</div></div>
</div>

What happens:

  1. .flex-container becomes a Flexbox container.
  2. flex-direction: column makes its direct children (.row) appear from top to bottom.
  3. min-height: 100vh gives the outer container at least the viewport height.
  4. In a column layout, the main axis is vertical, so justify-content: center moves the group of rows to the vertical center.
  5. Each .row becomes another Flexbox container.
  6. A row uses the default flex-direction: row, so its main axis is horizontal.
  7. justify-content: center centers the numbered .flex-item horizontally inside that row.

The result is a vertically centered stack of rows, with one horizontally centered item in every row.

Real World Use Cases

Flexbox centering is common in many interfaces:

  • Empty states: Center a “No search results” message and action button in a content panel.
  • Login pages: Center a sign-in card inside the viewport.
  • Loading screens: Center a spinner and status text both horizontally and vertically.
  • Dashboards: Put controls or status cards in vertically stacked, centered sections.
  • Product cards: Center an icon, title, and price within a card.
  • Dialogs and modals: Center the dialog within an overlay.
Take Quiz

Real Codebase Usage

In real projects, developers often use Flexbox with clear, reusable layout classes or component styles.

Center a page section

.page-empty-state {
  min-height: 60vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 1rem;
}

gap adds consistent spacing between direct flex children without assigning margins to every item.

Center a modal

.modal-overlay {
  position: fixed;
  inset: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 1rem;
}

Use nested layouts intentionally

A common pattern is:

  • Outer container controls the position of sections.
  • Inner container controls the content inside each section.
.settings-page {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.settings-section {
  display: flex;
  justify-content: center;
}

This avoids relying on one parent to align descendants that are not its direct flex items.

Common Mistakes

Forgetting that Flexbox only aligns direct children

This does not center .flex-item within .row:

.flex-container {
  display: flex;
  justify-content: center;
}

The direct children are .row, not .flex-item. Make .row a flex container too:

.row {
  display: flex;
  justify-content: center;
}

Using the wrong axis

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

This horizontally centers items in a column layout. It does not vertically center the group. Add justify-content: center for vertical centering.

Expecting vertical centering without container height

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

If the container is only as tall as its content, vertical centering has no visible effect. Give it available space:

.container {
  min-height: 100vh;
}

Styling an inline span as though it were a box

span {
  width: 200px;
  height: 150px;
}

An inline element does not normally honor width and height. Use a block-like display:

span {
  display: flex;
}

Or use a div when the element represents a layout box.

Missing the class selector

row {
  width: 100%;
}

This targets an HTML element named <row>, not class="row". Use a period for a class:

.row {
  width: 100%;
}

Comparisons

Situationjustify-content controlsalign-items controls
flex-direction: rowHorizontal positionVertical position
flex-direction: columnVertical positionHorizontal position
ApproachBest forLimitation
FlexboxAligning items in one dimension or simple two-axis centeringDirect children are the items being aligned
CSS GridAligning items in rows and columnsCan be more than needed for a simple one-row layout
margin: 0 autoHorizontally centering one fixed or max-width blockDoes not vertically center and needs a constrained width
text-align: centerCentering inline text or inline elementsDoes not center block-level layout elements vertically

For a single centered box, Flexbox is often the clearest choice. For a full two-dimensional dashboard or gallery, CSS Grid may better describe the layout.

Take Quiz

Cheat Sheet

/* Horizontal and vertical center in a row layout */
.container {
  display: flex;
  justify-content: center;
  align-items: center;
}

/* Stack children, then center the stack vertically and horizontally */
.container {
  display: flex;
  flex-direction: column;
  justify-content: center; /* vertical in column mode */
  align-items: center;     /* horizontal in column mode */
  min-height: 100vh;
}

/* Center one child inside every full-width row */
.row {
  width: 100%;
  display: flex;
  justify-content: center;
}

/* Make an inline span behave like a sized box */
.flex-item {
  display: flex;
  justify-content: center;
  align-items: center;
}
  • display: flex activates Flexbox.
  • justify-content works on the main axis.
  • align-items works on the cross axis.
  • flex-direction changes which physical direction each axis represents.
  • Alignment affects direct children only.
  • Use height or min-height when vertical centering needs visible space.
  • Use .row for a class selector, not row.

FAQ

How do I center a div both horizontally and vertically with Flexbox?

Set the parent to display: flex, then use justify-content: center and align-items: center. Give the parent a height or min-height if vertical centering should be visible.

Why is justify-content: center not centering my nested element?

It centers only the parent container's direct flex items. If the target is nested inside another element, make that inner parent a Flexbox container as well.

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

justify-content aligns along the main axis. align-items aligns along the cross axis. The direction changes when you use flex-direction: column.

How do I put Flexbox items one below another?

Use flex-direction: column on their Flexbox parent.

Why do width and height not work on my span?

A span is inline by default. Set display: inline-block, block, flex, or inline-flex, or use a block element such as div.

Do I need line-height to vertically center text in a box?

No. line-height can work for a single line, but display: flex; align-items: center; justify-content: center; handles single or multiple lines more reliably.

Should I use height: 100vh or min-height: 100vh?

Use min-height: 100vh when content may grow taller than the viewport. It keeps at least viewport height without forcing overflow from larger content.

Take Quiz

Mini Project

Description

Build a simple full-screen status page that displays several numbered task cards in a vertical stack. The stack should be centered in the viewport, and every card should center its own text without relying on line-height.

Goal

Create a vertically and horizontally centered stack of responsive task cards using nested Flexbox containers.

Requirements

Include a full-page container with at least the viewport height. Stack four task cards from top to bottom. Center the stack within the page vertically and horizontally. Center the text inside every card. Use gap for spacing between cards.

Take Quiz

Keep learning

Related questions

View more