What CSS vertical-align actually does
The vertical-align property aligns an element relative to the line box it sits in.
In plain English: it changes how an inline, inline-block, or table-cell element is positioned vertically compared to the text (and other inline-level elements) around it.
This is why vertical-align is perfect for things like:
- Aligning an icon next to text
- Aligning inline-block “chips” or badges with surrounding text
- Aligning inline images with text
- Vertically aligning content in
display: table-cell
It is not a general “center this div vertically” button. If you’re trying to vertically center content inside a block container, you usually want Flexbox, Grid, positioning, etc. For those approaches, see: Centering With CSS Interactive Tutorial.
The baseline: why vertical-align seems weird at first
Most inline content aligns to the baseline by default.
The baseline is the imaginary line your text “sits” on.
Letters like g, p, and y hang below it, so the line box includes a bit of extra space for descenders.
This is why an inline-block icon often looks slightly too low next to text: it’s baseline-aligned, not “visually centered.”
.icon {
vertical-align: baseline;
}
*,
::before,
::after {
box-sizing: border-box;
}
.demo-line {
font-family: ui-monospace, SFMono-Regular, monospace;
font-size: 22px;
line-height: 1.4;
padding: 14px;
border: 2px solid #111;
background: #f6f6f6;
}
.icon {
display: inline-block;
width: 34px;
height: 34px;
border: 2px solid #111;
background: #fff;
border-radius: 8px;
position: relative;
}
.icon::before {
content: "";
position: absolute;
inset: 6px;
border: 2px dashed #111;
border-radius: 6px;
}
.note {
margin-top: 10px;
font-family: ui-monospace, SFMono-Regular, monospace;
font-size: 14px;
opacity: 0.85;
}
Text with a little icon next to it.
Tip: baseline is the default, but middle often “looks” more centered for icons.
In that playground, the icon is display: inline-block, which makes it eligible for vertical-align.
Switching from baseline to middle is the classic “icon + text” fix.
CSS vertical-align: middle (center-ish)
The value people reach for most often is middle.
It aligns the middle of the element with the baseline plus half the x-height of the parent’s font.
That sounds complicated, but the practical result is: it usually makes icons and inline-block UI bits look vertically centered next to text.
.icon {
vertical-align: middle;
}
.icon {
vertical-align: baseline;
}
.icon {
vertical-align: top;
}
.icon {
vertical-align: bottom;
}
*,
::before,
::after {
box-sizing: border-box;
}
.demo {
font-family: ui-monospace, SFMono-Regular, monospace;
font-size: 24px;
line-height: 1.5;
padding: 16px;
border: 2px solid #111;
background: #f6f6f6;
}
.icon {
display: inline-block;
width: 40px;
height: 40px;
border: 2px solid #111;
border-radius: 10px;
background: #fff;
margin: 0 6px;
}
.icon::after {
content: "★";
display: grid;
place-items: center;
font-size: 22px;
}
Save to favorites
Notice how “center” is not an actual value for vertical-align.
If you mean “center next to text,” you almost always mean middle.
CSS vertical-align: top
top aligns the top of the element with the top of the line box.
This can be useful when you have inline-block elements with different heights and you want their tops to line up.
.box {
vertical-align: top;
}
.box {
vertical-align: baseline;
}
.box {
vertical-align: bottom;
}
*,
::before,
::after {
box-sizing: border-box;
}
.line {
font-family: ui-monospace, SFMono-Regular, monospace;
font-size: 18px;
line-height: 1.3;
padding: 16px;
border: 2px solid #111;
background: #f6f6f6;
}
.box {
display: inline-block;
width: 90px;
border: 2px solid #111;
background: #fff;
padding: 10px;
border-radius: 10px;
margin-right: 10px;
}
.tall {
padding-block: 24px;
}
Tall Short Short
CSS vertical-align: bottom
bottom aligns the bottom of the element with the bottom of the line box.
This is useful when you want inline elements to “sit” on the same bottom edge visually.
In practice, if you’re aligning UI blocks of different heights, you’ll often compare top and bottom to see which one looks best for your layout.
Text-specific values: text-top, text-bottom, sub, super
There are a few values that are designed for aligning elements relative to text metrics:
text-top: aligns with the top of the parent’s texttext-bottom: aligns with the bottom of the parent’s textsub: a subscript-like alignmentsuper: a superscript-like alignment
.unit {
vertical-align: super;
}
.unit {
vertical-align: sub;
}
.unit {
vertical-align: text-top;
}
.unit {
vertical-align: text-bottom;
}
.unit {
vertical-align: baseline;
}
*,
::before,
::after {
box-sizing: border-box;
}
.demo-text {
font-family: ui-monospace, SFMono-Regular, monospace;
font-size: 28px;
line-height: 1.4;
padding: 18px;
border: 2px solid #111;
background: #f6f6f6;
}
.unit {
display: inline-block;
padding: 2px 8px;
border: 2px solid #111;
border-radius: 10px;
background: #fff;
font-size: 14px;
}
Temperature: 23°C
Real subscripts/superscripts are also commonly done with semantic HTML like <sub> and <sup>.
But the property values sub and super can be handy when your element isn’t literally a sub/sup tag.
Lengths and percentages: fine-tuning vertical-align
vertical-align can also accept a length (like 6px) or a percentage.
This shifts the element up or down relative to the baseline.
- Positive values move the element up
- Negative values move the element down
This is great for those “it’s almost perfect, but not quite” icon alignment moments.
.icon {
vertical-align: 0px;
}
*,
::before,
::after {
box-sizing: border-box;
}
.row {
font-family: ui-monospace, SFMono-Regular, monospace;
font-size: 24px;
line-height: 1.6;
padding: 18px;
border: 2px solid #111;
background: #f6f6f6;
}
.icon {
display: inline-block;
width: 42px;
height: 42px;
border: 2px solid #111;
border-radius: 12px;
background: #fff;
margin-inline: 8px;
position: relative;
}
.icon::before {
content: "";
position: absolute;
inset: 10px;
border-radius: 999px;
border: 2px dashed #111;
}
Download file.zip
This kind of micro-adjustment is especially common for icon fonts, SVG icons, and inline badges.
Try to keep these tweaks small, though. If you find yourself pushing vertical-align: 18px, it’s usually a sign that the layout method should change.
CSS vertical-align with images (and the gap under images)
Inline images behave like text characters: they sit on the baseline.
That means browsers often leave a tiny gap under an inline <img> to make room for descenders.
One common fix is:
- Set the image to
display: block, or - Keep it inline and set
vertical-align: middle(orbottom)
.avatar {
vertical-align: middle;
}
.avatar {
vertical-align: baseline;
}
.avatar {
vertical-align: bottom;
}
.avatar {
vertical-align: top;
}
*,
::before,
::after {
box-sizing: border-box;
}
.card {
font-family: ui-monospace, SFMono-Regular, monospace;
font-size: 18px;
line-height: 1.5;
padding: 16px;
border: 2px solid #111;
background: #f6f6f6;
max-width: 520px;
}
.avatar {
display: inline-block;
width: 56px;
height: 56px;
border: 2px solid #111;
border-radius: 14px;
margin-right: 10px;
}
.caption {
margin-top: 10px;
font-size: 14px;
opacity: 0.85;
}
Monospace Penguin posted a new update.
Switch vertical-align values and watch how the image sits in the text line.
If your goal is “no baseline gap under the image,” another super common fix is simply:
img { display: block; }.
That’s not vertical-align, but it’s often the cleanest way when the image doesn’t need to behave like text.
CSS vertical-align div, text, image (what people really mean)
Searches like “CSS vertical align div” usually mean one of these:
- “Align an icon/image with text” (yes,
vertical-alignis perfect for that) - “Vertically center content inside a box” (that’s usually Flexbox/Grid/positioning)
- “Align columns in a layout” (again, not
vertical-align, usually Flex/Grid)
So here’s the rule of thumb:
-
If your element is inline or inline-block (or inside a table-cell), use
vertical-align. - If your element is a normal block-level div in a layout, you probably want to look at the Centering With CSS Interactive Tutorial.
Table-cells: where vertical-align feels most straightforward
In tables (or elements behaving like table cells), vertical-align is wonderfully literal:
it aligns content to the top/middle/bottom of the cell.
.cell {
vertical-align: middle;
}
*,
::before,
::after {
box-sizing: border-box;
}
.table {
display: table;
width: 100%;
border-collapse: collapse;
font-family: ui-monospace, SFMono-Regular, monospace;
}
.row {
display: table-row;
}
.cell {
display: table-cell;
border: 2px solid #111;
padding: 14px;
background: #f6f6f6;
height: 140px;
width: 50%;
}
.box {
border: 2px solid #111;
background: #fff;
border-radius: 14px;
padding: 10px 12px;
display: inline-block;
}
Short contentTaller content
with a second line
to show alignment.
If you’ve ever thought “vertical-align is easy in tables but weird elsewhere,” that’s because the table-cell case matches our mental model: top/middle/bottom of a rectangle. Inline formatting is based on baselines and line boxes.
Vertical-align not working: a checklist
If vertical-align seems to do nothing, it’s usually one of these:
-
The element isn’t eligible.
vertical-alignapplies to inline, inline-block, and table-cell. If your element isdisplay: block, it won’t respond the way you expect. - You’re trying to align a whole block layout. For real vertical centering inside containers, use Flexbox/Grid (see the Centering With CSS Interactive Tutorial).
-
There’s no meaningful “neighbor” in the same line.
vertical-alignaligns relative to the line box and other inline-level items. If your element is alone or on its own line, you may not notice changes. -
Line-height is doing most of the visual work.
Sometimes adjusting
line-height(on the parent text) is the real fix. - You’re inside a Flexbox or Grid item and expecting vertical-align to center things. Flex/Grid have their own alignment systems (again: use the centering tutorial).
Vertical-align cheat sheet
-
Use case: icon/badge/image next to text
- Try
vertical-align: middlefirst
- Try
-
Use case: align tops of mixed-height inline-block elements
- Use
vertical-align: top
- Use
-
Use case: align bottoms of mixed-height inline-block elements
- Use
vertical-align: bottom
- Use
-
Use case: table cells
top,middle,bottombehave very intuitively
-
Not the right tool: vertically centering content inside a normal block
div- Use Flexbox/Grid/positioning instead: Centering With CSS Interactive Tutorial
Wrap-up: vertical-align in one sentence
vertical-align is for aligning inline-ish things (inline, inline-block, table-cell) relative to the line box or cell,
not for globally centering block layouts.
Once you think “baseline,” it stops feeling like magic and starts feeling like a very specific (and very useful) wrench.
