How to center anything with CSS
By Flavio Copes
A complete CSS centering guide for text, blocks, Flexbox, Grid, absolute positioning, viewport layouts, unknown sizes, overflow, and common traps.
Centering in CSS is easy once you answer 2 questions:
- What are you centering?
- Which layout system controls it?
Text, a block, a Flexbox item, and an absolutely positioned dialog need different tools.
This guide gives you the right recipe for each case.
The quick answer
To center one element both horizontally and vertically, use Grid:
.container {
display: grid;
place-items: center;
}
Or use Flexbox:
.container {
display: flex;
align-items: center;
justify-content: center;
}
Both approaches work when the container has extra space to distribute.
If the container has no height beyond its content, there is no vertical space to center within.
Center text horizontally
Use text-align: center on the containing block:
.message {
text-align: center;
}
This centers inline content inside .message:
- text
- links
- inline images
- inline and inline-block elements
It does not center the .message block itself.
Center a block horizontally
Give the block a width smaller than its container, then use automatic inline margins:
.article {
width: min(70ch, 100%);
margin-inline: auto;
}
margin-inline follows the writing direction. It is the logical equivalent of setting both left and right margins.
The block needs a constrained width. A block already occupying the full available width has nowhere to move.
max-width is often more flexible:
.article {
max-width: 70ch;
margin-inline: auto;
}
Center an image
Images are inline elements by default. Turn the image into a block and use automatic margins:
.photo {
display: block;
max-width: 100%;
margin-inline: auto;
}
If you want to center every inline item inside a wrapper, text-align also works:
.photo-wrapper {
text-align: center;
}
The first approach controls one image. The second controls all inline content in the wrapper.
Center with Flexbox
Flexbox is the best choice when items sit in one row or column.
.container {
display: flex;
align-items: center;
justify-content: center;
}
justify-content works on the main axis.
align-items works on the cross axis.
With the default flex-direction: row, the main axis is horizontal and the cross axis is vertical.
Center in a vertical Flexbox layout
When the direction changes, the axes change too:
.container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
Now justify-content centers vertically because the main axis runs from top to bottom.
This is why memorizing “justify means horizontal” creates bugs. Think in axes instead.
Read my Flexbox guide for the complete layout model.
Center one Flexbox item
Use align-self to override one item’s cross-axis alignment:
.special-item {
align-self: center;
}
Automatic margins can also absorb free space:
.special-item {
margin: auto;
}
This is useful for a single item, but it can make a larger Flexbox layout harder to reason about. Use container alignment when all items follow the same rule.
Center several Flexbox lines
align-content controls the collection of flex lines, not one item.
It matters when wrapping creates multiple lines and the container has extra cross-axis space:
.tags {
display: flex;
flex-wrap: wrap;
align-content: center;
min-height: 20rem;
}
For a single flex line, use align-items.
Center with CSS Grid
Grid offers the shortest general recipe:
.container {
display: grid;
place-items: center;
}
place-items is shorthand for:
.container {
align-items: center;
justify-items: center;
}
It centers each grid item inside its grid area.
This is ideal for an empty state, loader, illustration, or one-card layout.
Read my CSS Grid guide when you need the full grid model.
Center the Grid tracks
place-content centers the grid itself inside the container:
.gallery {
display: grid;
grid-template-columns: repeat(2, 10rem);
place-content: center;
min-height: 30rem;
}
The distinction is:
place-itemsaligns items inside their grid areasplace-contentaligns the grid tracks inside the container
If the tracks already fill the container, place-content has no free space to distribute.
Center one Grid item
Use place-self:
.featured-card {
place-self: center;
}
It combines align-self and justify-self.
Center content inside a normal block
Modern CSS lets align-content center content in a block container:
.card {
align-content: center;
min-height: 20rem;
}
This is useful when you only need vertical centering and do not want to switch the element to Flexbox or Grid.
Use text-align: center as well when the inline content should be horizontally centered:
.card {
align-content: center;
min-height: 20rem;
text-align: center;
}
For older browser requirements, Flexbox or Grid remains the safer choice.
Center an element in the viewport
Use a container that fills the viewport:
.page {
display: grid;
place-items: center;
min-height: 100dvh;
}
dvh tracks the dynamic viewport height. It behaves better on mobile browsers when the address bar appears or disappears.
A practical fallback is:
.page {
min-height: 100vh;
min-height: 100dvh;
}
Browsers that do not understand dvh keep the earlier vh value.
Center an absolutely positioned element
Absolute positioning is useful for overlays and anchored UI.
If the element has an unknown size, position its center at 50% and translate it back by half its own size:
.dialog {
position: absolute;
inset-block-start: 50%;
inset-inline-start: 50%;
transform: translate(-50%, -50%);
}
The containing block must establish a positioning context:
.container {
position: relative;
}
The percentages in inset-* refer to the container. The percentages in translate() refer to the element itself.
Center a fixed dialog
For a viewport overlay, use fixed positioning and inset:
.dialog {
position: fixed;
inset: 0;
margin: auto;
width: min(32rem, calc(100% - 2rem));
height: fit-content;
}
This centers the dialog and keeps a safe gap on narrow screens.
If the dialog content might be taller than the viewport, add a size limit and scrolling:
.dialog {
max-height: calc(100dvh - 2rem);
overflow: auto;
}
Center an element of known size
You might see negative margins in older code:
.box {
position: absolute;
top: 50%;
left: 50%;
width: 20rem;
height: 10rem;
margin-top: -5rem;
margin-left: -10rem;
}
This works, but it duplicates the dimensions and breaks when they change.
Use transforms, Grid, or Flexbox instead.
Center without forcing overflow
Perfect centering can hide the start of oversized content.
Imagine a short mobile viewport with a tall login form. Centering it vertically can push the first fields above the visible area.
Flexbox supports safe alignment:
.page {
display: flex;
align-items: safe center;
justify-content: center;
min-height: 100dvh;
}
When centering would overflow unsafely, safe center falls back toward the start edge.
Browser behavior can vary across layout modes, so test the exact layout with oversized content.
Another reliable pattern is automatic margins with padding:
.page {
display: flex;
min-height: 100dvh;
padding: 1rem;
}
.form {
margin: auto;
}
Center in different writing modes
Physical words such as left and right assume a writing direction.
Logical properties adapt automatically:
.article {
margin-inline: auto;
}
Grid and Flexbox alignment also use layout axes instead of hardcoded screen directions.
This makes them a better default for multilingual interfaces.
Why vertical centering sometimes does nothing
Vertical centering requires available height.
This container grows only as tall as its content:
.container {
display: flex;
align-items: center;
}
There is no extra cross-axis space, so you see no movement.
Give the container a meaningful height or minimum height:
.container {
display: flex;
align-items: center;
min-height: 20rem;
}
Why margin: auto sometimes does nothing
Horizontal auto margins need free space and a block with a constrained width.
This element already fills the available width:
.box {
margin-inline: auto;
}
Add a width or max-width:
.box {
max-width: 40rem;
margin-inline: auto;
}
Which centering method should you choose?
Use this short guide:
- text or inline content:
text-align: center - one block horizontally:
margin-inline: auto - one item on both axes: Grid with
place-items: center - a row or column of items: Flexbox alignment
- grid tracks inside a larger area:
place-content: center - one positioned overlay: inset plus
margin: autoor translate - one item with overflow risk: automatic margins or safe alignment
My default is Grid for one centered item and Flexbox for a row or column.
The important part is not memorizing a trick. Identify the layout system, its axes, and where the free space lives.
Related posts about css: