Quick take: Centering a single element on both axes takes one line in modern CSS:
place-items: centeron a Grid parent. Flexbox does the same job withjustify-contentplusalign-items. The old vertical-centering pain is gone, as long as you avoid themargin: autoandheight: 100%traps.
CSS centering used to be a running joke. Horizontal was fine, but vertical centering meant tables, negative margins, or ghost pseudo-elements. That era is over. To center a div in CSS today, you reach for flexbox or Grid, and the whole thing collapses into two or three declarations. Flexbox sits at roughly 99% global support and Grid at about 97% as of 2026 per MDN, so there's no compatibility reason to keep using hacks. This guide walks through every method that still matters, when to use each, and the handful of gotchas that trip people up.
How do you center a div horizontally?
Horizontal centering has three answers depending on what you're centering. For a block-level element with a set width, margin: 0 auto is the classic move and it still works everywhere.
.card {
width: 320px;
margin: 0 auto; /* left and right margins share leftover space */
}
For inline or inline-block content, text-align: center on the parent pushes everything to the middle of the line box. And for a flex child, justify-content: center centers along the main axis. Which one do you pick? If the element has an intrinsic or explicit width and lives in normal flow, use margin: auto. Otherwise, let a flex parent do it. One catch worth knowing: margin: auto needs that width to be less than the container, otherwise there's no leftover space to split and nothing appears to move.
.toolbar {
display: flex;
justify-content: center; /* centers children along the row */
}
How do you center a div vertically?
This is the one that made people cry for years. In plain document flow you can't just say "put this in the vertical middle," because block layout distributes height differently than width. The modern fix is to make the parent a flex or grid container and align on the cross axis.
.parent {
display: flex;
align-items: center; /* vertical centering, finally */
height: 400px;
}
I still remember shipping a hero section in 2015 with a top: 50%; margin-top: -140px hack, then watching it break the moment the copy changed length. When I rebuilt it with align-items: center, the fragile pixel math just vanished. That's the real win here: the browser measures the child for you, so content of any height stays centered.
How do you center on both axes at once?
Here's where the methods really diverge. Three approaches cover almost every case, and I'll rank them.
Grid is the shortest. One property does both axes:
.parent {
display: grid;
place-items: center; /* horizontal + vertical in one line */
min-height: 100dvh;
}
Flexbox needs two properties but reads clearly and plays nicely with sibling elements:
.parent {
display: flex;
justify-content: center; /* horizontal (main axis) */
align-items: center; /* vertical (cross axis) */
min-height: 100dvh;
}
Absolute positioning with a transform is the fallback for when you can't touch the parent's display mode, like centering an overlay or a modal on top of existing layout.
.overlay {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%); /* pull back by half its own size */
}
The transform trick works because top: 50% moves the element's top edge to the middle, then translate(-50%, -50%) shifts it back by half of its own width and height. No fixed dimensions required, which is why it survived long after the negative-margin version died. The one snag is that the parent needs position: relative or the offsets resolve against the wrong ancestor, and you can end up centering against the whole viewport by accident. If you want a deeper look at when a two-dimensional grid beats a one-dimensional flex row for the surrounding layout, I broke that down in CSS Grid vs Flexbox.
What's the difference between centering text and centering a block?
People conflate these two constantly, and it causes real confusion. text-align: center centers the inline content inside a box. It does nothing to the box itself.
<div class="banner">
<p>This text is centered by text-align.</p>
</div>
.banner {
text-align: center; /* moves the text, not the div */
width: 500px;
}
So if you want the 500px banner itself in the middle of the page and the text inside it centered too, you need both margin: 0 auto on the box and text-align: center for the content. They operate on different things. Miss that distinction and you'll swear the div "won't center" when it's actually doing exactly what you asked.
What are the most common centering gotchas?
A few traps show up over and over. First: margin: auto never centers vertically in normal flow, because the vertical auto margins resolve to zero. If you want the vertical middle, use flex or grid, not margins.
Second: the height: 100% trap. A percentage height only works if the parent has a defined height. Chain enough elements without one and your centered child silently collapses to content height.
/* This fails unless html and body also have height set */
.wrapper {
height: 100%;
display: grid;
place-items: center;
}
Reach for min-height: 100dvh on the outermost container instead, and skip the percentage-height chain entirely. Which brings up the third gotcha: use 100dvh, not 100vh. The old vh unit ignores mobile browser toolbars, so a full-screen centered element gets clipped under the address bar on phones. The dynamic viewport unit dvh accounts for that chrome as it slides in and out. This is one of those bugs you only catch on a real device, never in a desktop devtools preview.
Which method should you default to in 2026?
Default to flexbox. That's my honest take, even though Grid's place-items: center is one character shorter to think about. Flexbox reads well to the next developer, aligns siblings without extra work, and carries the highest browser support number of the bunch. Reserve Grid centering for when the element genuinely stands alone, and reserve absolute-plus-transform for overlays where you can't own the parent. If you can only memorize one snippet, memorize display: flex; justify-content: center; align-items: center. It'll cover nine out of ten centering jobs you hit this year, and you won't have to relearn it when the CSS spec adds the next shiny thing.