How to center anything with CSS

By

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:

  1. What are you centering?
  2. 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:

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:

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:

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.

Tagged: CSS · All topics
~~~

Related posts about css: