Home / Snippets / Layout /

Center with inline-block + vertical-align

Vertically center an element inside its container using inline-block display and vertical-align: middle — a pre-flexbox technique still useful for specific inline contexts.

Vertical center via inline-block + pseudo-element
Vertically centered
Icon aligned with text
Deadline: Friday
Widely Supported
layoutno-js

Quick implementation

/* Vertical center with inline-block + pseudo-element */
.ib-center {
  text-align: center;
  white-space: nowrap; /* prevent wrapping of the pseudo-element */
}

.ib-center::before {
  content: '';
  display: inline-block;
  height: 100%;
  vertical-align: middle;
}

.ib-center__item {
  display: inline-block;
  vertical-align: middle;
  white-space: normal; /* restore wrapping for content */
}

/* Simpler: align icon with text */
.icon-text {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

.icon-text svg {
  vertical-align: middle;
}

Prompt this to your LLM

Includes role, constraints, two framework variants, and edge cases to handle.

You are a senior frontend engineer explaining pre-flexbox centering patterns
that still have practical uses in modern code.

Goal: Vertically center content inside a fixed-height container using the
inline-block + pseudo-element technique, and separately demonstrate aligning
an icon with adjacent text using vertical-align: middle.

Technical constraints:
- The container gets text-align: center and white-space: nowrap.
- A ::before pseudo-element on the container is set to display: inline-block,
  height: 100%, and vertical-align: middle — this creates a full-height
  reference inline box.
- The content element gets display: inline-block and vertical-align: middle,
  which aligns it to the midpoint of the tallest inline element (the
  pseudo-element), centering it vertically.
- white-space: nowrap on the container prevents the pseudo-element from
  wrapping; restore white-space: normal on the content element so its
  own text can wrap normally.
- The container must have an explicit height (or min-height) — vertical
  centering only works when there is free space in the block direction.
- For the simpler icon-text alignment case, use display: inline-flex and
  align-items: center instead of the pseudo-element trick.
- Use oklch() for any color values — no hex or rgba.
- No JavaScript required.

Framework variant (pick one):
A) Vanilla CSS BEM classes .ib-center and .ib-center__item for the
   full vertical centering pattern, plus a .icon-text utility for
   the simpler icon-with-text case.
B) React component — VerticalCenter wraps a child in a div that
   applies the ::before trick via a CSS module or styled-component;
   accepts a height prop (string, default "12rem").

Edge cases to handle:
- If the content is taller than the container, it will overflow — add
  overflow: hidden to the container to clip it, or use min-height
  instead of height to let the container grow.
- In older IE, the pseudo-element approach required font-size: 0 on
  the container to eliminate the baseline gap — not needed in
  modern browsers, but worth noting for legacy codebase maintenance.
- The pseudo-element technique does not work in flex or grid containers
  — ::before and ::after become flex/grid items and lose their
  inline-block behavior. Use this only in standard block containers.
- For new code, prefer display: flex; align-items: center on the
  container — it achieves the same result with less code and handles
  variable-height content without the pseudo-element.

Return CSS only (or a React component if variant B is chosen).

How the pseudo-element trick creates a vertical midpoint

The inline-block vertical centering technique relies on a full-height reference element inside the container's inline formatting context. A ::before pseudo-element is set to display: inline-block, height: 100%, and vertical-align: middle. Because this pseudo-element stretches to the full height of the container, it establishes the tallest inline box — the one that defines where the "middle" is within the line box.

The content element is also set to display: inline-block; vertical-align: middle. The browser aligns the middle of each inline-block to a shared vertical midpoint within the line box. Since the pseudo-element's middle is the container's geometric center, the content's middle lands at the same point — the content is centered.

white-space: nowrap on the container is required to keep the pseudo-element and the content element on the same line. Without it, the full-height pseudo-element could wrap to a second line, collapsing to zero height and breaking the centering. white-space: normal is then restored on the content element so that its own text wraps normally.

When vertical-align is still the right tool

The full pseudo-element trick is rarely needed in new code — flexbox handles the same centering more cleanly. But vertical-align itself still has genuine uses. Aligning an SVG icon with adjacent text is the most common: vertical-align: middle on the icon nudges it to the text's visual midpoint, preventing the slight top-offset that appears when an inline <svg> sits on the text baseline.

For this simpler case, display: inline-flex; align-items: center on the wrapper is cleaner and more predictable than per-element vertical-align. The inline-flex approach does not require understanding inline formatting contexts or baseline alignment — both the icon and label are simply flex items aligned to the cross-axis center.

vertical-align also controls alignment within HTML table cells (display: table-cell) independently of flexbox or grid — a relevant detail when working with legacy table-based layouts covered in the table-cell centering snippet.

The baseline gap problem

Inline-block elements sit on the text baseline by default. When two inline-block elements are placed side by side and one of them contains text while the other does not, the empty element's bottom edge aligns to the baseline of the adjacent text, creating a visual gap beneath any content-bearing element. This is a common source of unexpected whitespace in inline-block layouts.

Solutions include adding vertical-align: middle (or any non-baseline value) to all inline-block elements in the row, or setting font-size: 0 on the container and restoring the font size on each child. For new layouts, avoid this class of problem entirely by using flexbox — flex items do not participate in inline formatting contexts and are immune to baseline gap issues.