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: flexturns the div into a flex container.align-items: centercenters 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.
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:
- The browser creates the
.statusbox with at least64pxof height. display: flexplaces the image and span next to each other in a row.- The image and text may have different natural heights.
align-items: centercalculates the vertical midpoint of the64pxcontainer.- Each direct child is positioned so its own midpoint matches that container midpoint.
gap: 8pxadds 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.
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-heightinstead of fixedheightwhen text could wrap or users may zoom in. - Use
gapfor spacing between flex items instead of adding one-off margins. - Use
justify-content: centeras well when content must be centered horizontally. - Use
flex-wrap: wrapwhen 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
| Technique | Best use | Key limitation |
|---|---|---|
display: flex; align-items: center | Centering mixed content such as text, images, and buttons in one row | Needs a container layout context; visible centering needs available height |
display: grid; place-items: center | Centering one item, or a small group, both vertically and horizontally | Often more than needed for a simple row |
line-height equal to height | One line of plain text in a fixed-height element | Fails for multi-line text and is awkward with icons or different font sizes |
vertical-align: middle | Aligning inline text and inline images on the same line | Does not center block children inside a normal div |
Absolute positioning with transform | Overlays and elements removed from normal document flow | Can 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;
}
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-itemscontrols vertical alignment;justify-contentcontrols horizontal distribution. - In a column: the axes switch, so
justify-contentcontrols vertical distribution. - Use
min-heightto create centering space without blocking larger content. - Use
gapfor spacing between flex items. - Use
vertical-align: middlemainly 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.
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
- Create a notification row with an icon, message, and dismiss button.
- Use Flexbox to vertically center the direct child elements.
- Use
gaprather than margins to space the items. - Allow the message to wrap without overlapping the button.
- Use a minimum height instead of relying on a fixed text offset.
Keep learning
Related questions
Angular ngClass Conditional Class Binding Explained
Learn how to use Angular ngClass for conditional classes, fix common binding mistakes, and understand why this template error happens.
Apply CSS to an iframe: Same-Origin Styling in HTML
Learn why parent-page CSS does not style iframe content, how same-origin rules work, and practical ways to style embedded pages safely.
Apply Multiple CSS Transforms: rotate() and translate()
Learn how to combine multiple CSS transform functions such as rotate() and translate(), understand transform order, and avoid overwritten rules.