Centering a div is the most googled CSS question on the planet, and the reason is simple: there is no single answer. There are six working techniques, and each one is built for a different scenario. Pick the wrong one and your box slides to the top, stretches to full width, or vanishes off screen.
This guide starts with a decision table so you can pick the right method in seconds, then gives copy-paste code for each one, followed by browser support notes and the mistakes that quietly break centering inside flex containers and absolutely positioned parents.
Pick your method in 5 seconds
Find the row that matches your situation, then jump to that method below.
| Your situation | Use this method | Axis |
|---|---|---|
| A block element with a fixed or max width inside a normal container | 1. margin-inline: auto | Horizontal |
| Text, icons, buttons or other inline content inside a box | 2. text-align: center | Horizontal |
| One or several children, unknown sizes, you control the parent | 3. Flexbox | Both |
| One child, shortest possible code, overlapping layers allowed | 4. Grid + place-items: center | Both |
| Modal, overlay, tooltip, badge that must sit on top without affecting layout | 5. position: absolute + transform | Both |
| You cannot turn the parent into flex or grid (legacy layout, third-party markup) | 6. align-content: center (block layout) | Vertical |

Method 1: margin auto (horizontal centering of a block)
This is the oldest and still the most useful trick for horizontal centering only. The element must be a block-level box and it must have a width smaller than its container. The browser then splits the leftover space evenly between the left and right margins.
.card {
width: 600px; /* or max-width: 600px */
margin-inline: auto; /* same as margin-left: auto; margin-right: auto */
}
The classic version still works everywhere:
.card {
max-width: 600px;
margin: 0 auto;
}
When it fails
- No width set: a block element is already 100% wide, so there is nothing left to distribute.
- The element is
display: inlineorinline-block: auto margins do nothing horizontally. - The element is floated or absolutely positioned without
insetvalues.
Pro tip: use max-width instead of width so the box shrinks on small screens instead of overflowing.
Method 2: text-align: center (inline content)
If what you want to center is text, an image, an <a> button or an inline-block box, set the rule on the parent, not on the element itself.
.banner {
text-align: center;
}
/* the child can stay inline-block */
.banner .cta {
display: inline-block;
padding: 12px 24px;
}
This is the right tool when the child has no fixed width and you want it to hug its content. It is also inherited, so remember to reset it (text-align: left or start) on deeper children if you only wanted the one line centered.

Method 3: Flexbox (the default answer for both axes)
Three lines on the parent center anything inside it, horizontally and vertically, whatever its size. It is argued more carefully on joshwcomeau.com.
.parent {
display: flex;
justify-content: center; /* horizontal (main axis) */
align-items: center; /* vertical (cross axis) */
min-height: 100vh; /* the parent needs height to center inside */
}
Horizontal only
.parent {
display: flex;
justify-content: center;
}
Vertical only
.parent {
display: flex;
align-items: center;
min-height: 400px;
}
The flex-direction trap
The properties are tied to the axis, not to the screen. If you add flex-direction: column, the two properties swap roles:
| flex-direction | justify-content: center | align-items: center |
|---|---|---|
| row (default) | Horizontal | Vertical |
| column | Vertical | Horizontal |
Shortcut: place-items: center also works in flexbox in every current browser, and margin: auto on a flex child centers it on both axes at once. That second trick is the safest option when the content can overflow, because justify-content: center can cut off the top of a scrolling box while auto margins do not.
.parent { display: flex; min-height: 100vh; }
.child { margin: auto; } /* centered both ways, overflow-safe */
Method 4: CSS Grid with place-items: center
The shortest correct answer in modern CSS. Two declarations on the parent, nothing at all on the child.
.parent {
display: grid;
place-items: center;
min-height: 100vh;
}
place-items is shorthand for align-items (block axis) and justify-items (inline axis). If you prefer to center the whole group of children as a block instead of each item in its own cell, use place-content: center instead. There’s a good explainer over at freecodecamp.org.
Grid vs Flexbox: which one
- Grid when you have a single child, or when children should stack in the same cell (hero image with text on top: give both
grid-area: 1 / 1). - Flexbox when children sit in a row or column and you also need
gap, wrapping orflex: 1sizing behaviour.
Both are equally well supported, so this is a readability decision, not a compatibility one.

Method 5: position absolute + transform (modals and overlays)
Use this when the centered element must be removed from the document flow: modal windows, dropdown panels, loaders, badges over an image.
.parent {
position: relative; /* mandatory: creates the containing block */
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
How it works: top: 50% and left: 50% place the top-left corner of the child in the middle of the parent. translate(-50%, -50%) then pulls the box back by half its own width and height, which is why this works even when you do not know the size of the child.
The inset + margin auto variant
If the child has a known width and height, you can skip transforms entirely. This version avoids the half-pixel blur that translate can cause on text at odd sizes.
.child {
position: absolute;
inset: 0; /* top/right/bottom/left: 0 */
width: 320px;
height: 180px;
margin: auto;
}
Centering a modal in the viewport
.modal {
position: fixed;
inset: 0;
display: grid;
place-items: center;
}
Or, if you use the native dialog element, the browser already centers it for you: dialog:modal is centered in the viewport by default, and you can style the backdrop with dialog::backdrop.
Method 6: align-content: center in normal block layout
This is the newest technique and the one most articles still miss. Since 2024, align-content works on block containers, not just flex and grid. That means you can center a child vertically without converting the parent into a flex or grid container, so all existing block behaviour (floats, margins, text-align, column flow) stays intact.
.parent {
align-content: center; /* vertical centering, still display: block */
height: 400px;
}
Combine it with text-align: center or margin-inline: auto for the horizontal axis and you get full centering with zero layout side effects. It is the go-to fix when a third-party widget or an email-style template breaks the moment you set display: flex on a wrapper.

Browser support at a glance
| Technique | Support status | Notes |
|---|---|---|
| margin auto, text-align | Universal | Safe everywhere, including HTML email clients |
| margin-inline | All modern browsers | Fall back to margin: 0 auto for very old clients |
| Flexbox | Universal (modern syntax since 2015) | The default safe choice for production |
| Grid + place-items | Universal in current browsers | Longhands align-items / justify-items if you need maximum caution |
| absolute + translate | Universal | Watch for blurry text on non-integer pixel values |
| align-content in block layout | Chrome / Edge 123+, Safari 17.4+, Firefox 125+ (since 2024) | Widely available now; older browsers simply ignore it, so nothing breaks |
If you must support an old browser, wrap the newer rule in a feature query so the old engine keeps a usable fallback:
.parent { padding-block: 80px; } /* fallback spacing */
@supports (align-content: center) {
.parent { padding-block: 0; align-content: center; height: 400px; }
}
7 mistakes that break centering
- The parent has no height. Vertical centering needs vertical space to distribute. A div with no explicit height is exactly as tall as its content, so
align-items: centerhas nothing to do. Fix: setmin-height,height,aspect-ratioor let a grid row define it. - Using height: 100% without a chain. A percentage height only resolves if every ancestor also has a height. Use
min-height: 100vh(or100dvhon mobile to avoid the browser toolbar jump) instead of chaininghtml, body, div { height: 100% }. - Applying the centering to the child instead of the parent.
justify-content,align-items,place-itemsandtext-alignall belong on the container. Onlymargin: auto,align-selfandjustify-selfgo on the child. - Forgetting position: relative on the parent. An absolutely positioned child looks for the nearest positioned ancestor. If there is none, it centers itself against the viewport or the page, which is the classic “my modal is centered on the wrong thing” bug. Note that
transform,filterandwill-changeon an ancestor also create a containing block, which can steal the reference unexpectedly. - Fighting the flex item stretch. By default flex items stretch on the cross axis. When you set
align-items: centerthe child stops stretching and shrinks to its content, which can look like it “lost its width”. Give it an explicitwidth,max-widthor usealign-self: stretchon the items that should still fill. - justify-content: center plus overflow. If the centered content is taller or wider than the container, centering pushes the overflow out on both sides and the start of the content becomes unreachable when scrolling. Use
margin: autoon the flex child, orsafe center(justify-content: safe center), which falls back to start alignment when the content overflows. - Percentage transforms on the wrong box.
translate(-50%, -50%)is relative to the element’s own size, including padding and border unless you setbox-sizing: border-box. Inconsistent box sizing is a frequent cause of a box being off by a few pixels.

Quick copy-paste snippets
Perfect center, shortest version
.parent {
display: grid;
place-items: center;
min-height: 100dvh;
}
Centered content container (the page wrapper pattern)
.wrapper {
width: min(1200px, 100% - 2rem);
margin-inline: auto;
}
Center a div horizontally only, without flex
.box {
max-width: 480px;
margin: 0 auto;
}
Center an image inside a card
.card img {
display: block;
margin-inline: auto;
}
Center a div with position: absolute
.parent { position: relative; }
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
FAQ
What is the easiest way to center a div in CSS?
Set display: grid and place-items: center on the parent, plus a height. Two lines, no changes to the child, works on both axes for content of any size.
How do I center a div horizontally only?
Give the div a width (or max-width) and add margin-inline: auto. If the content is inline, such as text or a button, use text-align: center on the parent instead.
How do I center a div vertically in CSS?
Three options: display: flex; align-items: center on the parent, display: grid; align-content: center, or the newer align-content: center directly on a block container. In all three cases the parent must have a height or min-height.
How do I center a div with position: absolute?
Add position: relative to the parent, then on the child use top: 50%; left: 50%; transform: translate(-50%, -50%);. If the child has a fixed width and height, inset: 0; margin: auto; gives the same result without a transform.
How do I center a div without flexbox?
Use margin: 0 auto for horizontal centering, text-align: center for inline content, align-content: center for vertical centering in block layout, or absolute positioning with a transform. CSS Grid is also a non-flex option. css-tricks.com goes into the numbers.
Why is my div not centering vertically?
Almost always because the parent has no height to work with. A block element is only as tall as its content, so there is no free vertical space to split. Add min-height, and check that you are not using a percentage height whose ancestor chain has no defined height.
Should I use Flexbox or Grid to center a div?
For one element, Grid with place-items: center is shorter. For a row or column of elements where you also need gaps, wrapping or flexible sizing, Flexbox is the better fit. Performance is equivalent.
Final takeaway
There is no universal way to center a div, but there is always one right way for your situation:
- Block with a width:
margin-inline: auto - Inline content:
text-align: center - Anything, both axes, parent under your control: Flexbox or Grid
- Overlay that must not affect layout: absolute + translate
- Parent you cannot convert:
align-content: center
Bookmark the decision table at the top and you will never guess again. If you build landing pages or product pages with us at AdProductsToGo, these snippets drop straight into your stylesheet without touching the rest of your layout.

