Home / Blog / How to center a div

How to Center a Div in CSS

Published August 28, 2026 · 10 min read · by the CSS DNA team

Quick answer: To center a div both ways, put display: grid; place-items: center on its parent. If you cannot change the parent’s display type, align-content: center alone now centers vertically in plain block layout — no flexbox, no grid, no wrapper element. For horizontal centering of a block with a width, margin-inline: auto is still the shortest correct answer.

Centering is not one problem. It is four, and picking the wrong method is almost always the result of not noticing which one you have: are you centering along one axis or both, is the thing you are centering a block or a line of text, do you control the parent, and does the parent have a height to center inside of.

The thing most centering articles are now wrong about

You no longer need a flex or grid container to center something vertically. Since 2024, align-content works in ordinary block layout, which means one property on the parent does the job:

.parent {
  height: 300px;
  align-content: center;   /* that is the whole thing */
}

No display: flex. No wrapper div. The children stay block-level, so margins, floats and text flow behave exactly as they did before — which is the part flexbox always cost you.

Verified support: align-content in block layout shipped in Chrome and Edge 123, Safari 17.4 and Firefox 125, all in the first half of 2024. Can I Use puts global support at about 88%, so treat it as an enhancement on a site with meaningful legacy traffic rather than the only method in your stylesheet. Note also that MDN’s own box alignment in block layout guide still says browsers do not support this — that page is out of date; the Chrome shipping post and the browser compatibility data are the ones to trust.

One caveat worth knowing before you use it: the distribution values — space-between, space-around, space-evenly — do nothing in block layout, because all the block’s content is treated as a single alignment subject. Only the positional values (center, start, end) have an effect.

Try each method

Centering playground

Pick a method. The box below is a real child of a real container, restyled live — and the CSS shown is exactly what is applied.

child

display: grid · both axes

.parent {
  display: grid;
  place-items: center;
}

The seven methods, and when each is right

MethodCentersUse it when
display: grid; place-items: centerBoth axesThe default answer. Shortest correct code for one child, and it works for many.
display: flex; align-items: center; justify-content: centerBoth axesYou already have a flex container, or you need gap and wrapping behaviour for several children.
align-content: centerVerticalYou must keep the parent in block layout — the children rely on normal flow, floats or text wrapping.
margin-inline: autoHorizontalA block-level element with a definite width. Still the least code for the most common case.
text-align: centerHorizontalInline content — text, links, inline-block boxes, images.
position: absolute; inset: 0; margin: autoBoth axesThe element must be taken out of flow, e.g. an overlay above siblings.
top: 50%; translate: -50% -50%Both axesYou do not know the element’s size and it must be absolutely positioned. The classic fallback.

Both axes, one child: use grid

.parent {
  display: grid;
  place-items: center;
}

place-items is shorthand for align-items and justify-items. Two words, both axes, and it does not care about the child’s size or whether it has a width. If you find yourself writing three properties to center one thing, this is the one you wanted.

Horizontal only: use auto margins

.child {
  width: 600px;      /* or max-width */
  margin-inline: auto;
}

margin-inline sets the left and right margins in one property, and it follows writing direction, which margin: 0 auto does not. The width is not optional: a block element with no width already fills its parent, so there is no leftover space for auto to split.

Out of flow: absolute plus auto margins

.parent { position: relative; }
.overlay {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 320px;
  height: 180px;
}

Setting all four offsets to zero gives the box more room than it needs on both axes, and margin: auto divides the surplus evenly. This one needs a known width and height. When you do not have them, reach for the transform version instead:

.overlay {
  position: absolute;
  top: 50%;
  left: 50%;
  translate: -50% -50%;
}

Use the standalone translate property rather than transform: translate(-50%, -50%) — it leaves transform free for rotation or scale, so a hover animation cannot accidentally wipe out your centering. That collision is one of the most common causes of a modal that jumps on hover.

Wondering how a site you like centered something? CSS DNA shows the computed layout for any element you hover — display type, alignment properties, box model and the rule that actually won — without opening DevTools and hunting through the cascade. Add it free.

Why your centering is not working

The parent has no height

This is the single most common cause. Vertical centering divides leftover vertical space, and a block-level parent with no height set is exactly as tall as its content — so there is no leftover space and nothing moves. The fix is to give the parent a height, a min-height, or make it a grid or flex item that stretches:

.parent {
  min-height: 100svh;   /* not 100vh — see below */
  display: grid;
  place-items: center;
}

Prefer 100svh to 100vh for full-screen centering on mobile. vh is measured against the largest possible viewport, so with the browser’s address bar visible, a 100vh box is taller than the screen and your centered content sits slightly below the true middle.

You set align-items on the child

The alignment properties go on the container, not the thing being centered. align-items and justify-content on a child do nothing unless that child is itself a flex or grid container with children of its own. The exception is align-self and justify-self, which are the per-child overrides.

margin: auto with no width

A block element with no width fills the inline axis completely. There is no space left over, so the automatic margins compute to zero. Add a width or a max-width and it centers immediately.

justify-content did nothing in a column

In flexbox, justify-content aligns along the main axis and align-items along the cross axis — and flex-direction: column swaps which is which. In a column, vertical centering is justify-content: center and horizontal centering is align-items: center, the opposite of the row case. Grid does not have this problem, because justify-* is always inline and align-* is always block.

An ancestor is squashing it

When the CSS on the element looks right and it still will not center, the cause is usually further up the tree — a parent with an unexpected display, a stray align-items: flex-start three levels above, or a height that collapsed. Walking the ancestor chain in DevTools works; so does reading the computed styles for each ancestor in one pass.

Centering text is a different job

text-align: center centers inline content inside a block — text, links, images, anything inline-block. It does not move the block itself. And vertical centering of a single line of text is often best done with line-height equal to the box height, which avoids layout entirely:

.badge {
  height: 32px;
  line-height: 32px;   /* single line only */
  text-align: center;
}

This breaks the moment the text wraps to two lines, so keep it for badges, chips and buttons with guaranteed short labels. For anything that can wrap, use grid.

What to reach for, in order

  1. Both axes, you control the parent: display: grid; place-items: center.
  2. Horizontal only, block with a width: margin-inline: auto.
  3. Vertical only, parent must stay block: align-content: center.
  4. Inline content: text-align: center.
  5. Out of flow, size unknown: absolute plus translate: -50% -50%.

Everything else — negative margins, display: table-cell, ghost pseudo-elements with vertical-align: middle — is a workaround for browsers that no longer exist. If a tutorial hands you one of those in 2026, it was written for a different web.

Frequently asked questions

What is the best way to center a div?

For one element centered on both axes, display: grid; place-items: center on the parent is the shortest correct answer. It needs no width or height on the child, works for one child or many, and does not change how the child sizes itself. Use flexbox instead when you need gap, wrapping or per-item alignment control.

How do I center a div both horizontally and vertically?

Give the parent a height and use display: grid; place-items: center. The height matters: vertical centering distributes leftover vertical space, and a block parent with no height is exactly as tall as its content, so there is nothing to distribute. min-height: 100svh is the usual choice for a full-screen centered layout.

How do I center a div without flexbox or grid?

Use margin-inline: auto with a width for horizontal centering, and align-content: center on the parent for vertical centering. The second works in plain block layout in Chrome and Edge 123+, Safari 17.4+ and Firefox 125+, at roughly 88% global support, so pair it with a fallback if you support older browsers.

Why does margin: auto not center my div vertically?

In normal block flow, automatic top and bottom margins compute to zero — the specification only distributes leftover space on the inline axis. Vertical automatic margins do work in flex and grid containers, and for absolutely positioned elements that have all four offsets set, which is why position: absolute; inset: 0; margin: auto centers on both axes.

Why is my div not centering?

The four usual causes are: the parent has no height, so there is no vertical space to distribute; the alignment property was put on the child instead of the container; margin: auto was used without a width; or flex-direction: column swapped which axis justify-content controls. Check the parent’s computed height first — it accounts for most cases.

Does align-content work without flexbox?

Yes, since 2024. align-content applies to block containers and table cells as well as flex and grid containers, so align-content: center vertically centers the contents of a plain block. Only the positional values work — the distribution values such as space-between have no effect in block layout, because the content is treated as a single alignment subject.

What is the difference between place-items and place-content?

place-items sets align-items and justify-items, positioning each item inside its own grid area. place-content sets align-content and justify-content, positioning the whole grid inside the container. With a single item in an implicit single-cell grid, both centre it — but they diverge as soon as there is more than one item or the tracks are smaller than the container.

How do I center an absolutely positioned div?

If you know its width and height, use inset: 0; margin: auto. If you do not, use top: 50%; left: 50%; translate: -50% -50%. Prefer the standalone translate property over transform: translate(), so a later transform for a hover or animation does not overwrite the centering offset.

Why is my full-screen centered content slightly too low?

Because 100vh on mobile is measured against the viewport with browser chrome hidden, so the box is taller than the visible area and the centre point falls below the middle of the screen. Use 100svh — the small viewport height — or 100dvh if you want the box to resize as the address bar shows and hides.

See how any site laid it out

Hover any element to read its display type, alignment, box model and the rule that won — plus fonts, colors and design tokens, computed in your browser.

Add CSS DNA to Chrome — Free