Question

Vertically Center Text in a Div with CSS Flexbox

cssvertical-alignment

Question

How can I vertically center text inside a <div>? The following markup contains an image, bold text, and regular text, but the text is not positioned in the vertical middle as intended. Using margin-top has not produced the desired result.

<div id="column-content">
  <img src="https://i.sstatic.net/12qzO.png" alt="Example icon">
  <strong>1234</strong>
  yet another text content that should be centered vertically
</div>
#column-content {
  display: inline-block;
  border: 1px solid red;
  position: relative;
}

#column-content strong {
  color: #592102;
  font-size: 18px;
}

img {
  margin-top: -7px;
  vertical-align: middle;
}

What is the correct CSS approach for vertically centering this content within the <div>?

Short Answer

You will learn why vertical centering requires available height, why margins are usually the wrong tool, and how to use Flexbox to center text and images reliably inside a container.

Concept

Vertical alignment depends on what is being aligned and the layout context around it.

A <div> normally grows to fit its content. If it has no extra height, there is no visible vertical space in which to move its text upward or downward. Setting margin-top on an item changes its outside spacing; it does not define a dependable “center within the parent” rule.

For a container with a known height or min-height, modern CSS uses Flexbox:

  • display: flex turns the div into a flex container.
  • align-items: center centers its direct children on the cross axis.
  • In the default row direction, the cross axis is vertical.

This works well when the content includes a mixture of text, icons, buttons, and images. It also adapts better than manually chosen negative margins when font sizes or image dimensions change.

The older vertical-align property is different: it aligns inline-level elements such as text and inline images within a line of text. It does not vertically center ordinary block content inside a block container.

Mental Model

Think of a container as a tall shelf and its contents as objects placed on that shelf.

If the shelf is exactly as tall as its objects, there is nowhere to move them—they already fill the available space. Give the shelf a height, then tell Flexbox: “place all objects halfway between the top and bottom of this shelf.”

align-items: center is that instruction. A negative top margin is more like lifting one object by a guessed number of pixels: it may look correct today, but it can fail when the object or shelf changes.

Take Quiz

Syntax and Examples

Use Flexbox on the parent element.

.container {
  display: flex;
  align-items: center;
  min-height: 80px;
}
<div class="container">
  <img src="icon.png" alt="Icon">
  <strong>1234</strong>
  <span>Yet another text content that is vertically centered.</span>
</div>

A complete version of the original example could be written as follows:

<div id="column-content">
  <img src="https://i.sstatic.net/12qzO.png" alt="Example icon">
  <strong>1234</strong>
  <span>Yet another text content that should be centered vertically</span>
</div>
#column-content {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 60px;
  border: 1px solid red;
}

#column-content strong {
  color: #592102;
  font-size: 18px;
}

#column-content img {
  display: block;
}

inline-flex makes the container participate in surrounding text like an inline element while still using Flexbox for its contents. Use display: flex instead when the container should take up an entire row or block.

The gap property adds consistent spacing between direct flex items. Wrapping the plain text in a <span> makes it an explicit flex item, which is clearer and easier to style.

Step by Step Execution

Consider this example:

<div class="status">
  <img src="icon.png" alt="Success">
  <span>Saved successfully</span>
</div>
.status {
  display: flex;
  align-items: center;
  min-height: 64px;
  gap: 8px;
  border: 1px solid #999;
}

What happens:

  1. The browser creates the .status box with at least 64px of height.
  2. display: flex places the image and span next to each other in a row.
  3. The image and text may have different natural heights.
  4. align-items: center calculates the vertical midpoint of the 64px container.
  5. Each direct child is positioned so its own midpoint matches that container midpoint.
  6. gap: 8px adds horizontal space between the icon and message without using margins.

If the text wraps onto two lines, the entire text block remains vertically centered alongside the image.

Real World Use Cases

Vertical centering appears throughout interfaces:

  • Navigation bars: center links, profile images, and notification icons in a fixed-height header.
  • Buttons: center a label and optional icon inside a button.
  • Status messages: align an error, warning, or success icon with a message.
  • List rows: center an avatar, name, and action button in a contact or product row.
  • Cards: center empty-state messages or loading indicators within a panel.
  • Table-like layouts: align data and controls consistently when rows have a minimum height.

For most of these cases, Flexbox is the straightforward default because it handles unequal child heights and changing content well.

Take Quiz

Real Codebase Usage

In production CSS, developers typically make alignment part of a reusable component rule rather than applying pixel offsets to individual elements.

A common icon-and-label pattern:

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

.icon-label__icon {
  width: 1em;
  height: 1em;
  flex: 0 0 auto;
}
<button class="icon-label" type="button">
  <svg class="icon-label__icon" aria-hidden="true" viewBox="0 0 16 16"></svg>
  <span>Download</span>
</button>

Useful project patterns include:

  • Use min-height instead of fixed height when text could wrap or users may zoom in.
  • Use gap for spacing between flex items instead of adding one-off margins.
  • Use justify-content: center as well when content must be centered horizontally.
  • Use flex-wrap: wrap when a row must remain usable on narrow screens.
  • Keep alignment rules on the parent; avoid correcting each child with arbitrary offsets.

For example, to center content both vertically and horizontally:

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

Common Mistakes

Expecting vertical-align to center a div's contents

/* This does not vertically center normal block children in the div. */
.container {
  vertical-align: middle;
}

vertical-align affects inline, inline-block, and table-cell alignment in specific contexts. It is not a general-purpose parent alignment property. Use Flexbox for container content.

Forgetting to provide extra height

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

This is valid, but if the container has only the natural height of its children, centering may not look different. Add height or, more safely, min-height when a taller area is intended.

.container {
  display: flex;
  align-items: center;
  min-height: 60px;
}

Using negative margins as alignment fixes

img {
  margin-top: -7px;
}

This may compensate for a particular image and font combination, but it can break when the font, browser, image, zoom level, or text size changes. Use layout rules such as Flexbox first.

Using justify-content for vertical alignment in a row

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

With the default flex-direction: row, justify-content centers horizontally. For vertical centering, use align-items: center.

Using height when content can grow

A fixed height can cause text to overflow or be clipped when translated text becomes longer or when users increase font size. Prefer min-height unless a strict fixed-size component is required.

Comparisons

TechniqueBest useKey limitation
display: flex; align-items: centerCentering mixed content such as text, images, and buttons in one rowNeeds a container layout context; visible centering needs available height
display: grid; place-items: centerCentering one item, or a small group, both vertically and horizontallyOften more than needed for a simple row
line-height equal to heightOne line of plain text in a fixed-height elementFails for multi-line text and is awkward with icons or different font sizes
vertical-align: middleAligning inline text and inline images on the same lineDoes not center block children inside a normal div
Absolute positioning with transformOverlays and elements removed from normal document flowCan complicate responsive layouts and overlap other content

For the original image-and-text row, Flexbox is usually the best choice. If the desired layout is a single message centered in the middle of a larger box both ways, CSS Grid is also concise:

.message-box {
  display: grid;
  place-items: center;
  min-height: 160px;
}
Take Quiz

Cheat Sheet

/* Vertical center direct children in a horizontal row */
.row {
  display: flex;
  align-items: center;
  min-height: 60px;
}

/* Center both horizontally and vertically */
.centered {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 200px;
}

/* Keep the flex container inline with surrounding text */
.inline-row {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

/* When items should stack vertically */
.column {
  display: flex;
  flex-direction: column;
  justify-content: center; /* Vertical in a column */
  min-height: 200px;
}
  • Default Flexbox direction is row.
  • In a row: align-items controls vertical alignment; justify-content controls horizontal distribution.
  • In a column: the axes switch, so justify-content controls vertical distribution.
  • Use min-height to create centering space without blocking larger content.
  • Use gap for spacing between flex items.
  • Use vertical-align: middle mainly for inline elements, not general div layout.

FAQ

Why is my text not visibly vertically centered with Flexbox?

The parent may not have extra height. Add a height or min-height, then apply align-items: center.

How do I center text vertically and horizontally in a div?

Use Flexbox with both alignment properties:

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

Should I use margin-top to vertically center text?

Usually no. Margins are fixed offsets, not centering rules. They are fragile when content sizes change.

Does vertical-align: middle work on a div?

Not in the usual block layout. It is mainly for inline, inline-block, and table-cell alignment contexts.

What is the difference between flex and inline-flex?

Both create a flex container for their children. flex behaves like a block-level element; inline-flex behaves like an inline-level element in its parent layout.

Can Flexbox center multiple lines of text?

Yes. The full multi-line text block is centered as one flex item.

Should I use height or min-height for vertically centered content?

Use min-height when content may grow. Use a fixed height only when the component truly must have an exact height.

Take Quiz

Mini Project

Description

Build a reusable notification row containing an icon, a message, and a dismiss button. The row should remain vertically aligned even if the message wraps onto multiple lines.

Goal

Create a responsive notification component whose icon, text, and button are vertically centered using Flexbox.

Requirements

  1. Create a notification row with an icon, message, and dismiss button.
  2. Use Flexbox to vertically center the direct child elements.
  3. Use gap rather than margins to space the items.
  4. Allow the message to wrap without overlapping the button.
  5. Use a minimum height instead of relying on a fixed text offset.
Take Quiz

Keep learning

Related questions

View more