How to center a div in CSS: six ways, and when to use each
Centering horizontally is easy enough; vertically is where it goes wrong. Here are the six ways that work today, when to pick each one, and a few food trucks for you to center yourself, right in this page.
Christophe, founder of Lurndo
· 10 min read
The easiest way to center a div in CSS is flexbox on the parent: display: flex, justify-content: center and align-items: center. The child then sits in the middle, both horizontally and vertically. With grid, place-items: center does the same, margin-inline: auto centers horizontally only, and since October 2026 align-content: center on a plain block is Baseline widely available in every major browser.

How do you center a div horizontally and vertically?
Make the parent a flex container and let it center its children: display: flex, justify-content: center and align-items: center. That's the shortest way to the middle on both axes, and it works with any content: one button, a card or a group of food trucks. The rules go on the parent, not on the div you want to move: putting them on the child is the first classic slip.
.parent {
display: flex;
justify-content: center;
align-items: center;
min-height: 300px;
}Watch that min-height. By default a block is only as tall as its content, so there's nothing to center vertically: the child already touches the top and the bottom. Give the parent a height or a min-height, and only then will you see the child drop to the middle. A missing height is the best-known reason why "vertical centering doesn't work".
Try it now. On the tall square of the Wheels & Meals food truck festival, the client in our flexbox module, three trucks stand against the left, stretched to the full height. The square is already 200 pixels tall, so there's plenty of room. After you answer, the check also runs your CSS on a square with one more truck and longer names, so a fixed margin won't get you there.
Try it: center the trucks
Use flexbox to put the trucks together in the middle of the square, across and in height.
.square { display: flex;}<link rel="stylesheet" href="style.css"><main> <section class="square tall"> <div class="truck chips">Chips</div> <div class="truck ice-cream">Ices</div> <div class="truck pizza">Pizza</div> </section></main>body { margin: 0; font-family: system-ui, sans-serif; background: #fff8ec; color: #2b2118;}header { padding: 12px 16px; background: #264653; color: #ffffff;}header h1 { margin: 0; font-size: 1.5rem;}nav a { padding: 6px 10px; border-radius: 999px; color: #ffffff; text-decoration: none;}main { padding: 0 16px 24px;}.slogan { margin: 16px 0 0;}.square { margin: 16px 0; padding: 12px; border-radius: 18px; background-color: #efe6d4; background-image: radial-gradient(rgb(110 90 60 / 0.16) 1px, transparent 1.5px); background-size: 14px 14px; box-shadow: inset 0 0 0 1px rgb(110 90 60 / 0.14);}.square.tall { height: 200px;}.square.narrow { max-width: 250px;}/* A real truck: the cab, awning and wheels are only for the look. The truck fits inside the box, so its nose never hides under the next truck, and it stretches with the box. */.truck { position: relative; isolation: isolate; margin-bottom: 6px; padding: 16px 14px 12px; color: #ffffff; font-weight: 700;}.truck::before { content: ""; position: absolute; z-index: -1; inset: -3px 0 -1px 0; border-style: solid; border-width: 32px 20px 12px 12px; border-image: url(truck-taco.png) 128 80 48 48 fill round stretch; filter: drop-shadow(0 3px 3px rgb(43 33 24 / 0.25));}.truck::after { content: ""; position: absolute; z-index: -1; left: 12px; right: 4px; bottom: -3px; height: 12px; background: url(wiel.png) left / 12px no-repeat, url(wiel.png) right / 12px no-repeat;}.chips { color: #3a2a00;}.chips::before { border-image-source: url(truck-friet.png);}.taco::before { border-image-source: url(truck-taco.png);}.pizza::before { border-image-source: url(truck-pizza.png);}.waffle::before { border-image-source: url(truck-wafel.png);}.ice-cream { padding-top: 30px; padding-bottom: 26px; color: #4a1030;}.ice-cream::before { border-image-source: url(truck-ijs.png);}.curry { color: #3a1f00;}.curry::before { border-image-source: url(truck-curry.png);}.burger::before { border-image-source: url(truck-burger.png);}.soup::before { border-image-source: url(truck-soep.png);}.card { padding: 4px 16px; border-radius: 12px; background: #ffffff; box-shadow: 0 1px 2px rgb(43 33 24 / 0.08);}.card h2 { font-size: 1.15rem;}footer { padding: 12px 16px; background: #264653; color: #ffffff;}The page you just changed ran in your own browser. Lurndo checks it on what the browser makes of it: where every truck ends up, on that hidden square with four trucks too. So you don't have to copy our solution word for word. To see both axes first, with an inspector that draws them for you, start with display: flex and then justify-content.
How do you center a div with CSS grid?
Grid makes it even shorter: display: grid and place-items: center on the parent. place-items is shorthand for align-items and justify-items together, and it puts every child in the middle of its own cell. For a single child, like a message in an empty box or a logo on a tile, it's the shortest rule there is. place-items has worked in all major browsers since January 2020 (MDN).
.parent {
display: grid;
place-items: center;
min-height: 300px;
}With more than one child, things change. A grid without columns stacks its children, each in a row of its own, and those rows share the parent's height. Each child is then centered in its own row, not together with the others in the middle of the box. To keep the group together, use place-content: center or flexbox. Aligning in a cell shows the difference on a campsite full of tents.
On the web, flexbox is the clear favorite. According to Chrome Platform Status, 84.4% of page loads in Chrome used flexbox on November 3, 2026 (Chrome Platform Status), against 46.5% for grid (Chrome Platform Status). Grid has been growing fast, though: the Web Almanac found it on 2% of mobile pages in 2019 and on 12% by 2022 (Web Almanac).
- Flexbox84.4%
- Grid46.5%
How do you center a div horizontally with margin: 0 auto?
For a block that only needs to sit in the middle horizontally, like the main content of a page, you don't need flexbox. Give it a width or a max-width and set the left and right margins to auto: the browser splits the leftover space evenly between both sides. margin: 0 auto is the classic way to write it. margin-inline: auto is the modern one, and it has worked in all major browsers since April 2021 (MDN).
main {
max-width: 48rem;
margin-inline: auto;
}Is margin: 0 auto not working? Then the block almost always has no width. Without width or max-width, a block is as wide as its parent, and there's nothing left to share: auto becomes zero. Vertically, auto does nothing in a plain block, which is why this way only centers horizontally. The lesson on centering with margin auto shows the margins move in the box model as you type.
How do you center vertically without flexbox or grid?
With align-content: center, the newest way of the six. It now works on a plain block, with display: block, and its content moves to the middle vertically. Chrome and Edge 123, Safari 17.4 and Firefox 125 shipped it in spring 2024, and since October 16, 2026 it's Baseline widely available (webstatus.dev). A feature gets that label 30 months after the last major browser caught up (web.dev).
.message {
min-height: 200px;
align-content: center;
text-align: center;
}The upside: you don't touch the HTML, and the children stay ordinary blocks instead of flex items that shrink or stretch. When it reached all three browser engines in April 2024, Rachel Andrew wrote on web.dev that vertical centering, once close to impossible, had already been made easier by flexbox and grid, and that it now works in plain blocks too (web.dev).
Yet you rarely see it. In the centering guides we read for this article, in English and in Dutch, none says it's ready to use yet. Even MDN's centering recipe shows only flexbox and grid (MDN). So if you learn it now, you're a step ahead of most tutorials.
- March 2018Flexbox and transform become Baseline widely available
- January 2020place-items works in all major browsers
- April 2020Grid becomes Baseline widely available
- April 2021inset and margin-inline work in all major browsers
- April 2024align-content on a plain block works in all three browser engines
- October 2026align-content on a plain block becomes Baseline widely available
Source: webstatus.dev and MDN
How do you center a div with position: absolute?
Sometimes something has to sit on top of everything else: a dialog over the page, a play button on a photo. Then you take it out of the flow with position: absolute, and set the parent to position: relative so the child positions itself against that parent. With inset: 0 and margin: auto it lands in the middle, as long as the child has a width and a height. inset has worked in all major browsers since April 2021 (MDN).
.photo {
position: relative;
}
.play-button {
position: absolute;
inset: 0;
width: 64px;
height: 64px;
margin: auto;
}Don't know the size? Use the older trick. top: 50% and left: 50% put the child's top-left corner in the middle, and transform: translate(-50%, -50%) pulls it back by half its own width and height. That transform has been Baseline widely available since March 2018 (webstatus.dev). You can practice how a child positions itself against its parent in relative and absolute.
.dialog {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}An absolute element no longer counts toward its parent's height. So the parent doesn't grow when the dialog gets bigger, and long text can spill out or slide over the rest of the page. That's why this is the way for things that float above the page, not for its ordinary content.
Why doesn't text-align: center center my div?
Because text-align doesn't move the block itself, only what's inside it. MDN puts it precisely: the property sets the horizontal alignment of "the inline-level content inside a block element" (MDN). Text, links, an <img> or a button with display: inline-block move to the middle. The div itself stays as wide as its parent and doesn't move an inch.
For text, though, text-align: center is the right choice: a heading, a button under a form, a row of icons. Put it on the block around the text. Want to center an image? You have two routes: leave it inline and put text-align: center on the parent, or turn it into a block with display: block and margin-inline: auto.
.heading {
text-align: center;
}
.logo {
display: block;
margin-inline: auto;
}Which way to center, and when?
There's no best way, but there is a best way for each case. The question is always the same: do you want to center in one direction or in two, is it one child or a group, and can the element stay in the normal flow of the page? This table puts the six ways side by side.
| Way | Goes on | Direction | Pick it for |
|---|---|---|---|
| Flexbox | the parent | both | a group of items, and whenever in doubt |
place-items: center | the parent, as a grid | both | one child in a box |
margin-inline: auto | the block itself, with a width | horizontal | the main content of a page |
align-content: center | the parent, a plain block | vertical | text in a box, without flexbox |
position: absolute | the child, with the parent relative | both | something floating over the rest |
text-align: center | the block around the text | horizontal | text, links and images in a line |
When in doubt, start with flexbox: it works for one child and for ten, and the children stay in the flow. Grid is handy once the parent is a grid anyway. To learn to read both, with puzzles that get a little harder each time, see flexbox and grid practice. Every property is on the HTML and CSS cheat sheet, with an example.
Why isn't my div centering?
Almost always because of one of these five mistakes. They look harmless, and CSS never shows an error: nothing happens at all, or it works on your screen and not on someone else's. Go through them one by one before you start doubting your whole stylesheet.
- The parent has no height. A block is as tall as its content. Without a
heightormin-heighton the parent, there's nothing to center vertically, whichever way you use. - `text-align` on the block. It moves the text inside the block, not the block itself. For the div, pick one of the other ways.
- `margin: auto` without a width. A block without
widthormax-widthfills the whole line, so there's nothing left to share on either side. - `absolute` without a positioned parent. Without
position: relativeon the parent, the child positions itself against an ancestor further up, or against the page itself. Then it may end up in the middle of the first screen instead of inside its own box. - Fixed sizes that break with longer text. A
margin-left: 300pxor atop: 85pxis right for one screen width and one text. With a longer title or one more item, it's all off. Let the browser do the math, withautoorcenter.
You're not the only one who trips over this. In the State of CSS 2025, a survey with 5,506 respondents, people writing in about what's hard in layout named grid most (272 times), but also height (94 times), positioning (63 times) and alignment (55 times) (State of CSS).
How do you get centering right every time?
Centering doesn't stick because you learned six recipes by heart. It sticks once you've seen what each rule does. That's why the inspector in our lessons draws the flexbox axes and the grid lines under the page, and why we also check every solution on a variant with longer texts and one more item. Carry on with align-items or display: grid, or read the difference between HTML and CSS first. The first three modules are free.
Frequently asked questions
How do I center a div in CSS?
Put display: flex, justify-content: center and align-items: center on the parent. The child then sits in the middle, horizontally and vertically. Grid works too, with display: grid and place-items: center. Either way, give the parent a height, or there's nothing to center vertically.
Why is margin: 0 auto not working?
Almost always because the block has no width. Without width or max-width, a block is as wide as its parent, and there's no space left on either side to share. Or the element is inline, like a <span> or an <img>, and then auto just becomes zero. Make it a block first.
How do I center a div inside another div?
Put the centering rules on the outer div, the parent: display: flex, justify-content: center and align-items: center, plus a height. The inner div then sits in the middle both ways. To center it only horizontally, give the inner div a max-width and margin-inline: auto instead.
How do I vertically center text without flexbox?
Use align-content: center on the block around the text, and give that block a height. It has worked in Chrome, Edge, Firefox and Safari since 2024 and has been Baseline widely available since October 2026. For a single line, a line-height equal to the height works too, but that trick breaks once the text wraps onto two lines.
How do I center an image in CSS?
An image is inline by default, like a word in a sentence. So put text-align: center on the block around it, or make the image a block with display: block and margin-inline: auto. If it also needs to be centered vertically, use flexbox or grid on the parent, and give that parent a height.
Is align-content: center safe to use?
Yes, for everyday websites. It works in Chrome and Edge 123, Safari 17.4 and Firefox 125, all from spring 2024, and has been Baseline widely available since October 16, 2026. If you also have to support much older browsers, for example on a device that no longer updates, use flexbox instead.
Practise this in the course
Every lesson explains first and then lets you practise yourself, with a real browser in your browser.
- The cross axisFlexbox · Align-items
- CentringThe box model · Centring with margin auto
- Aligning items in their cellGrid · Aligning in a cell
- position, relative and absolutePositioning and responsive · Relative and absolute
Sources
- webstatus.dev, align-content in block layout (2026-10-16)
- web.dev (Rachel Andrew), align-content in block layout, in all three browser engines (2024-04-17)
- web.dev, Baseline
- webstatus.dev, Flexbox
- webstatus.dev, Grid
- webstatus.dev, 2D transforms
- MDN, place-items
- MDN, margin-inline
- MDN, inset
- MDN, text-align
- MDN, Center an element
- Chrome Platform Status, Feature popularity, flexbox (2026-11-03)
- Chrome Platform Status, Feature popularity, grid (2026-11-03)
- HTTP Archive, Web Almanac 2022, CSS (2022)
- State of CSS, State of CSS 2025, Layout (2025)
Christophe, founder of Lurndo
Christophe builds Lurndo from Belgium, with short, playful exercises for SQL, Excel, HTML & CSS and touch typing that show straight away what your answer does. On this blog, Christophe answers the questions people run into while learning, with sources you can check yourself.
Read next
HTML vs CSS: what's the difference, and how do they work together?Every web page has two layers, what's on it and how it looks. Here's how HTML and CSS split that work, and you'll write your first CSS rule right in this page.HTML & CSS · · 10 min read
How to calculate an average in Excel: blanks, zeros, conditions and weighted averagesIt's one function, yet averages go wrong all the time. See how AVERAGE works, what it skips, and how to average without zeros, with a condition or with weights, on real spreadsheets.Excel · · 11 min read