vertical-align

vertical-align

Last updated 2026-11-02

  • vertical-align
  • baseline
  • line box
  • inline-block
  • image gap
  • middle
On this page

vertical-align is badly named: it suggests "align anything vertically", while it only affects inline boxes and table cells, and it measures against the baseline, not the centre of a container.

Writing vertical-align: middle on a block-level div does nothing — the most common misuse.

Inline boxes only

It applies to:

  • inline elements;
  • inline-blocks and replaced elements (img, <video>, <input>);
  • table cells (td / th) — different semantics, out of scope here.

It does not apply to block-level elements, nor to flex / grid items (those use align-items / align-self).

So before using it, check that the target is "a small thing inside a line".

The values

Value Meaning
baseline default; the element's own baseline aligns to the parent line box's baseline
middle the element's midpoint aligns to "baseline + half the x-height"
text-top / text-bottom align to the top / bottom of the parent's content area
top / bottom align to the top / bottom of the line box
sub / super shift down / up a little (exact offset is browser- and font-dependent)
<length> shift from the baseline (positive is up)
<percentage> shift by a percentage of line-height

The top / bottom versus text-top / text-bottom distinction gets skipped often: the first pair is measured against the line box (including the space leading creates), the second against the content area (the font's extents). With a large line height they differ a lot.

Where the baseline comes from

The line box's baseline is not a fixed height; it is computed from what participates in that line:

  • with text present, the baseline of the text's font;
  • with only an inline-block, the baseline of its last line box;
  • if the inline-block has no content (or its overflow is not visible), its baseline is its bottom edge.

That last rule causes a good share of "why is this thing offset" surprises.

middle is not vertical centring

middle means "the element's vertical midpoint aligns to the parent's baseline plus half an x-height". It makes icons look aligned with text; it does not centre anything in a container.

To centre inside a container, use flex (align-items: center) or grid. Which is why in modern layout vertical-align is only for inline alignment.

The gap under images

The classic:

<div><img src="photo.jpg" alt=""></div>

A few pixels of blank space appear below the image. Because <img> is an inline replaced element with vertical-align: baseline: it sits on the baseline, and below the baseline there is still descender space (for the tails of g, p).

Three fixes:

img { display: block; }              /* cleanest: take it out of inline layout */
img { vertical-align: top; }         /* or middle / bottom */
div { line-height: 0; }              /* or zero the line height (careful with other content) */

display: block is the recommendation: an image is not text, so do not make it participate in a line box.

Trying it here

The two squares below are inline-block and sit on the baseline by default. Switch the option and watch them move relative to the text:

CSS Demo: vertical-align

Note that the options are complete rules (.box { … }): vertical-align has to act on the squares, not on the outer div.

Why the type tester does not offer it

Phase 1's type preview renders one block of text with no inline elements inside, so vertical-align has nothing to act on — it was left out on purpose (see docs/roadmap.md §5).

Where it is actually needed (aligning icons with text, images with captions) belongs in components, not in a type test.

Further reading