Question

Vertically Center Text in a Div with CSS Flexbox

csshtmlvertical-alignment

Question

How can I vertically center the text content inside a fixed-size <div> using CSS?

#box {
  height: 170px;
  width: 270px;
  background: #000;
  font-size: 48px;
  color: #fff;
  text-align: center;
}
<div id="box">
  Lorem ipsum dolor sit
</div>

What is the best way to center the text vertically while keeping it horizontally centered?

Short Answer

You will learn why vertical centering depends on the CSS layout system, how to use Flexbox as the usual solution, and when Grid or line-height is appropriate. You will also learn why some older techniques fail when text wraps onto multiple lines.

Concept

Vertical alignment is not controlled by text-align. The text-align property centers inline content horizontally; it does not move content up or down.

For a container such as a <div>, the most reliable modern solution is Flexbox. Flexbox lays out a container's direct children—or its text content—along two axes:

  • The main axis is horizontal by default.
  • The cross axis is vertical by default.

With display: flex, you can use:

  • justify-content: center to center content along the main axis.
  • align-items: center to center content along the cross axis.

Because the default main axis is horizontal, this combination centers content in both directions. It also continues to work when text wraps across multiple lines, the font size changes, or the container height changes.

Vertical centering is common in buttons, empty-state panels, dashboard tiles, loading areas, dialogs, and cards.

Mental Model

Think of the <div> as a rectangular picture frame and its text as a photo inside it.

  • text-align: center slides the photo left or right until it is centered.
  • Flexbox can also slide the photo up or down until it is centered.

Rather than calculating the text's height yourself, you tell the frame: “Place whatever is inside exactly in the middle.”

Take Quiz

Syntax and Examples

Use Flexbox on the container:

#box {
  width: 270px;
  height: 170px;
  background: #000;
  color: #fff;
  font-size: 48px;

  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
}
<div id="box">Lorem ipsum dolor sit</div>

justify-content: center centers the text horizontally. align-items: center centers it vertically. text-align: center is still useful if the text wraps: it centers each line within the available width.

Grid alternative

CSS Grid has a compact centering shorthand:

#box {
  width: 270px;
  height: 170px;
  display: grid;
  place-items: center;
  text-align: center;
}

place-items: center centers items in both the horizontal and vertical directions. For simple one-item or one-content-area centering, Grid is a clear alternative to Flexbox.

Single-line-only alternative

If the content is guaranteed to be exactly one line, line-height can match the container height:

#box {
  height: 170px;
  line-height: 170px;
  text-align: center;
}

This is not a good general-purpose technique because wrapping text creates multiple lines, each with a 170px line height.

Step by Step Execution

Consider this example:

#box {
  width: 270px;
  height: 170px;
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
}
<div id="box">Hello, world!</div>

What the browser does:

  1. It creates a box that is 270px wide and 170px high.
  2. display: flex turns #box into a flex container.
  3. The default flex direction is row, so the main axis runs from left to right.
  4. justify-content: center puts the text group in the horizontal middle of that row.
  5. The cross axis runs from top to bottom.
  6. align-items: center puts the text group in the vertical middle of the 170px height.
  7. If the text wraps, text-align: center centers the visible lines horizontally.

Real World Use Cases

  • Buttons: Center a label and an optional icon inside a button with a fixed or minimum height.
  • Status cards: Center “No results found” inside a dashboard panel.
  • Loading overlays: Place a spinner and message in the middle of an available area.
  • Profile placeholders: Center initials such as AB inside an avatar shape.
  • Error states: Keep an error message centered in an API-result area, even as the viewport changes.
  • Hero sections: Center a heading and call-to-action within a full-screen section.
Take Quiz

Real Codebase Usage

In real projects, developers usually prefer Flexbox for component-level alignment because it works well with dynamic content.

Center a group of elements

If the content includes more than text, wrap it in child elements and use flex-direction: column:

.empty-state {
  min-height: 240px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 12px;
  text-align: center;
}
<section class="empty-state">
  <p>No reports are available.</p>
  <button type="button">Refresh</button>
</section>

Here, flex-direction: column makes the main axis vertical. Therefore, justify-content: center now performs the vertical centering, while align-items: center performs horizontal centering.

Prefer flexible dimensions when possible

A fixed height can clip content if users increase font size or translated text becomes longer. Many codebases use min-height instead:

.notice {
  min-height: 170px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  text-align: center;
}

This preserves a useful minimum size while allowing the box to grow when necessary.

Common Mistakes

Expecting text-align to center vertically

/* This only centers text horizontally. */
#box {
  text-align: center;
}

Use Flexbox or Grid for vertical placement.

Using vertical-align on a normal block <div>

/* Usually has no vertical-centering effect on a block element. */
#box {
  vertical-align: middle;
}

vertical-align is mainly for inline-level elements and table cells. It does not vertically center ordinary block content in a block container.

Matching line-height to height when text can wrap

/* Breaks visually when the text wraps. */
#box {
  height: 170px;
  line-height: 170px;
}

Use this only for strictly single-line content. Choose Flexbox or Grid for normal text.

Forgetting the container needs usable height

Vertical centering is only visible when there is extra vertical space. If a container's height is determined entirely by its text, there is no empty area in which to center it.

Centering the wrong axis after changing direction

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

With flex-direction: column, align-items centers horizontally, not vertically. Add justify-content: center for vertical centering.

Clipping content with fixed height

Avoid relying on height for text-heavy components. Use min-height plus padding unless the design truly requires an exact height.

Comparisons

TechniqueBest forSupports wrapped text?Notes
FlexboxMost UI componentsYesFlexible, readable, and widely used.
Grid with place-itemsSimple two-axis centeringYesVery concise for a single centered area.
line-heightOne known single lineNoCan be convenient for small fixed labels.
vertical-align: middleTable cells and inline elementsDependsNot the standard solution for a block <div>.
Absolute positioning with transformsOverlays and special positioningYesUseful in specific layouts, but unnecessary for ordinary centering.

For the original fixed-size text box, Flexbox is typically the best default because it handles both one-line and multi-line text.

Take Quiz

Cheat Sheet

/* Flexbox: center content in both directions */
.container {
  display: flex;
  justify-content: center; /* main axis: horizontal by default */
  align-items: center;     /* cross axis: vertical by default */
  text-align: center;      /* centers wrapped text lines */
}
/* Flexbox with vertically stacked children */
.container {
  display: flex;
  flex-direction: column;
  justify-content: center; /* vertical when direction is column */
  align-items: center;     /* horizontal when direction is column */
}
/* Grid shorthand */
.container {
  display: grid;
  place-items: center;
}
/* One line only */
.container {
  height: 40px;
  line-height: 40px;
}
  • Use min-height rather than height when content may grow.
  • Add padding so text does not touch the edges on small screens.
  • Do not expect vertical-align: middle to center text inside a normal block <div>.

FAQ

How do I vertically center text in a div with CSS?

Make the div a flex container and use align-items: center. Add justify-content: center if you also want horizontal centering.

Does text-align: center vertically center text?

No. It controls horizontal alignment of inline content.

Is Flexbox better than line-height for vertical centering?

Usually, yes. Flexbox works with multiple lines, changing font sizes, and groups containing icons, buttons, or other elements. line-height is only suitable for one predictable line.

Why does vertical-align: middle not work on my div?

A normal <div> is a block-level element. vertical-align is intended primarily for inline-level elements and table cells, not for centering block content in a block container.

Can I use CSS Grid instead of Flexbox?

Yes. display: grid with place-items: center centers content in both directions and is an excellent option for simple layouts.

Should I use height or min-height for a centered text box?

Use min-height when content can be longer, translated, or enlarged by accessibility settings. Use a fixed height only when the component must have an exact size.

How do I center an icon and text together?

Put both inside a flex container. Use align-items: center to align them vertically in a row, or use flex-direction: column to stack and center them.

Take Quiz

Mini Project

Description

Build a reusable notification panel that centers an empty-state message and action button. This demonstrates how Flexbox handles multiple pieces of content, wrapping text, and flexible component height.

Goal

Create a responsive panel whose message and button remain centered horizontally and vertically.

Requirements

Use Flexbox to center the panel content in both directions. Use flex-direction: column so the message appears above the button. Use min-height rather than a fixed height. Center wrapped text and add spacing between the message and button. Include a visible button with accessible text.

Take Quiz

Keep learning

Related questions

View more