ESC

Type to search the knowledge base.

Centering Everything in CSS

Center with flex, grid, margin auto, and inset — horizontal, vertical, and both — plus the absolute-position and text-align traps.

beginner3 min read
  • css
  • centering
  • flexbox
  • grid

Centering is not one API. It depends on whether you control the parent, whether the child has a known size, and whether you mean the box or the text inside it. Most production cases collapse to flex or grid; the rest are historical footguns interviewers still poke.

Docs: MDN centering guide, Flexbox, Grid.

Default answers (2020s)

Flex — one child or a group

.center {
  display: flex;
  justify-content: center; /* main axis */
  align-items: center;     /* cross axis */
  min-height: 100vh;       /* needs a height to “vertical center” on the viewport */
}

Column flex: axes swap — justify-content becomes vertical.

Grid — dead simple for one item

.center {
  display: grid;
  place-items: center; /* align-items + justify-items */
  min-height: 100vh;
}

place-content centers the grid tracks when they don’t fill the container; place-items centers content in cells. For a single full-area child, place-items: center is the usual hammer.

Horizontal-only classics

/* Block box with a width */
.modal {
  width: min(32rem, 100% - 2rem);
  margin-inline: auto;
}

/* Inline / inline-block content */
.nav {
  text-align: center;
}

margin-inline: auto is the logical equivalent of margin-left/right: auto and respects writing mode.

Absolute center (known or unknown size)

.stage {
  position: relative;
  min-height: 12rem;
}

.stage__pin {
  position: absolute;
  inset: 0;
  width: max-content;
  height: max-content;
  margin: auto; /* works when inset is set and box has intrinsic size */
}

Or transform (size-agnostic):

.stage__pin {
  position: absolute;
  top: 50%;
  left: 50%;
  translate: -50% -50%; /* or transform: translate(-50%, -50%) */
}

Prefer flex/grid on the parent when you own the markup — absolute removes the element from flow and complicates responsive layouts.

Text vs box

.title {
  text-align: center; /* lines of text, inline content */
}

.icon {
  display: grid;
  place-items: center; /* the glyph box inside a fixed square */
  width: 2.5rem;
  height: 2.5rem;
}

text-align does not center a block-level box in its parent. That’s the classic beginner mix-up.

Full-page and app shells

html,
body {
  height: 100%;
}

body {
  margin: 0;
  display: grid;
  place-items: center;
}

For mobile browsers, 100vh includes UI chrome oddly; 100dvh (dynamic viewport) is often better for “center in visible viewport.”

.splash {
  min-height: 100dvh;
  display: grid;
  place-items: center;
}

Interview cheat sheet

Goal Technique
Center one box in parent Parent display: grid; place-items: center or flex + both alignments
Horizontally center block margin-inline: auto + width
Center text text-align: center
Center in viewport Grid/flex on body + min-height: 100dvh
Overlay spinner Absolute + inset/margin auto or grid on overlay

Footguns

  1. Centering with flex but parent height is auto — nothing to center in vertically.
  2. margin: auto on a flex item vs on a block — both valid, different contexts.
  3. Absolute centering without position: relative on the containing block.
  4. Using tables or negative margins in new code when flex/grid work.
  5. Centering a multi-line form and then fighting align-items: center stretching inputs — set align-items: stretch or widths explicitly.

Interview out-loud

“For unknown-size content I put display: grid; place-items: center on the parent, or flex with justify-content and align-items center. For a block with a defined width I use margin-inline: auto. I don’t use text-align to center boxes. Vertical centering always needs a definite block height or a viewport-sized container.”

Further reading

Related guides