Command Palette

Search for a command to run...

Hectal
PHASE 6Intermediate ~27 min· topic 5 of 5

Topic 6.5

Centering Anything

In one line

Pick the centering method by what you're centering: text-align: center for text and inline content, margin-inline: auto for a block with a width, place-items: center (Grid) or justify-content plus align-items (Flexbox) for both directions, and inset: 0; margin: auto or translate(-50%, -50%) for positioned boxes.

Think of it like this

Hanging a picture in the middle of a wall. You don't guess: you measure the space left over and split it equally on both sides. For a heavy frame you might use a rail that holds it in the middle automatically. CSS gives you both kinds: methods that share the leftover space equally (auto margins, Flexbox, Grid) and methods that measure from the middle (50% plus a shift back).

Words you'll meet

New words in this topic, in plain English. Come back here whenever one feels fuzzy.

Horizontal centring
Equal space on the left and right of something (along the inline axis).
Vertical centring
Equal space above and below something (along the block axis).
Leftover space
The room in a parent that a child doesn't fill. Centring splits it equally on both sides.
Auto margin
A margin set to auto, which takes a share of the leftover space.
`text-align: center`
Centres lines of text and inline content inside their block. It doesn't move block boxes.
`place-items: center`
In a grid, centres every item in its area both ways. Short for align-items plus justify-items.
`justify-content` / `align-items`
Flexbox properties that place items along the main axis and the cross axis.
`translate(-50%, -50%)`
A transform that shifts a box left and up by half of its own width and height.

Step by step

01Centre text

Put text-align: center on the element that contains the text. Each line is centred. If a button or image is inline or inline-block, it's centred too.

style.csswhole filecss
.hero {
  text-align: center;
}

02Centre a block horizontally

A page wrapper with a max-width and margin-inline: auto sits in the middle of wide screens and fills narrow ones. The two auto margins share the leftover width.

style.csswhole filecss
.container {
  max-width: 960px;
  margin-inline: auto;  /* same as margin-left: auto; margin-right: auto */
  padding-inline: 16px;
}

03Centre both ways with Grid

Two lines on the parent centre its child in both directions. Give the parent a height so there's vertical space to share.

style.csswhole filecss
.screen {
  display: grid;
  place-items: center;
  min-height: 100vh;
}

04Centre an overlay box

For a box laid over other content, position it. With a known size use inset: 0; margin: auto; with an unknown size use the 50% and translate pair.

style.csswhole filecss
.modal {
  position: fixed;
  inset: 0;
  margin: auto;
  width: min(90vw, 400px);
  height: fit-content;
}

.tooltip {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

05Choose the method

Follow the questions in order. The first matching answer is usually the simplest correct method.

Choose the methoddiagram
Rendering diagram…

Try it yourself

  1. 1

    Remove the parent's height

    In the first example, change .c's height: 100px to height: auto. Predict every top value. (All 0: with no extra vertical space, there's nothing to share. Vertical centring always needs a parent taller than the child.)

  2. 2

    Centre with align-content

    In the first example, add .block { align-content: center; }. Predict the block line. (left 70 top 30 in browsers that support align-content on block containers, Baseline 2024.)

  3. 3

    Make the safe keyword work

    In the third example, change justify-content: center to justify-content: safe center. Predict the first line. (child left: 0 in browsers that support safe in flex layout.)

Code & diagrams

Six ways to centre a box, measured New tab

A 60×40 box in a 200×100 parent is centred when it is 70px from the left and 30px from the top. Five methods get both. `margin-inline: auto` in normal flow only centres horizontally: vertical auto margins count as zero in block layout.

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

flex       left 70 top 30
grid       left 70 top 30
flexauto   left 70 top 30
abs        left 70 top 30
translate  left 70 top 30
block      left 70 top 0
Centring text and inline content New tab

`text-align: center` centres the heading, the paragraph and the inline-block button, because they are all lines of inline content inside the banner. Make the pill's text long enough to wrap and watch the `line-height` trick fall apart: each line is 40px tall.

Preview

Press Run to see the page.

Console

Nothing logged yet.
Safe centring: when the child is bigger than the parent New tab

With `justify-content: center`, the 300px child overflows **equally on both sides**, so its first 50px sit at a negative position that the scrollbar can't reach. Auto margins never go negative, so `margin: auto` falls back to the start edge and all the content can be scrolled to. The `safe` keyword (`justify-content: safe center`) asks for the same behaviour.

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

center child left: -50
auto child left: 0

Break it on purpose

Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.

Break #1

text-align on the wrong element

To centre a <div class="card" style="width: 300px"> on the page, write .card { text-align: center; }.

terminal
$ the page shows
── what you'll see ──
The text inside the card is centred, but the card itself stays stuck to the left edge.

Break #2

margin: auto that doesn't centre vertically

Try .box { width: 200px; height: 100px; margin: auto; } inside a tall normal <div> to centre it on the screen.

terminal
$ the page shows
── what you'll see ──
The box is centred horizontally but sits at the top of its parent.

Myth vs fact

Myth

Vertical centring in CSS is hard.

Fact

It was before Flexbox. Today display: grid; place-items: center on a parent with a height does it in two lines.

Myth

margin: 0 auto centres anything.

Fact

It centres a block box that has a width smaller than its parent. It does nothing for inline elements and nothing vertically in normal flow.

Myth

translate(-50%, -50%) is the best way to centre.

Fact

It's useful when the size is unknown and the box must overlap, but it can blur text on half pixels and takes the box out of flow. Prefer Grid or Flexbox when the box doesn't need to overlap.

Pro corner

Extra depth for experienced readers. New to this? Skip it for now and come back later.

  • ▸

    Centring with Flexbox or Grid can cause data loss: when the child is larger than the container, it overflows in both directions and the start side can't be scrolled to. Auto margins and the safe keyword avoid this. This matters for modals on short phone screens.

  • ▸

    place-items: center centres each item in its grid area; place-content: center centres the whole grid in the container. With one child and one auto-sized track they look the same, but they diverge once the grid has several tracks.

  • ▸

    For full-screen centring on mobile, min-height: 100vh can be taller than the visible area when browser toolbars are shown; 100dvh (dynamic viewport height) follows the toolbars (Phase 9 covers viewport units).

  • ▸

    Visual centre is not always mathematical centre: text has space above capitals and below the baseline, and icons often look low. Designers nudge by a pixel; text-box-trim (newer, not yet in every browser) trims the extra space above and below text so it can be centred precisely.

Remember this

  1. 1

    First ask two questions. What am I centering: text and inline content, or a box? And which way: horizontally (along the inline axis), vertically (along the block axis), or both? Most "centering doesn't work" bugs come from using an inline method on a block, or a horizontal method for a vertical problem.

  2. 2

    Text and inline content (text, links, inline-block buttons, images): text-align: center on the parent. It centres each line inside its line box. It doesn't move a block box, and it's inherited, so everything inside gets centred text too. For one line of text in a box of fixed height, line-height equal to the height centres it vertically, but it breaks if the text wraps.

  3. 3

    A block box horizontally: give it a width smaller than its parent (width, max-width or fit-content) and margin-inline: auto (the old margin: 0 auto). The browser splits the leftover space equally between the two auto margins. Without a width, a block already fills its parent, so there's no leftover space and nothing to see. In normal flow, margin-block: auto does not centre vertically: vertical auto margins in block layout count as zero.

  4. 4

    Both directions with Grid or Flexbox (the modern default): display: grid; place-items: center; on the parent centres the child in both directions with two declarations. With Flexbox: display: flex; justify-content: center; align-items: center;. Inside a flex or grid container, margin: auto on the child also centres it in both directions, because auto margins there absorb free space on both axes. The parent needs a height (or min-height: 100vh for a full screen) for vertical centring to be visible. Phases 7 and 8 explain these properties fully.

  5. 5

    Positioned boxes (overlays, modals, badges): with a known size, position: absolute; inset: 0; margin: auto; width: ...; height: ...; centres the box in its containing block, because the auto margins share the space between the four offsets. With an unknown size, top: 50%; left: 50%; transform: translate(-50%, -50%); puts the box's top-left corner at the centre, then shifts it back by half its own size (percentages in translate refer to the box itself). The transform can land on half pixels and blur text slightly.

  6. 6

    Newer and older options. align-content: center now works on plain block containers (Baseline 2024), so a block can centre its children vertically without becoming flex or grid. For a vertical centre in old table-like layouts, display: table-cell; vertical-align: middle; still works, and vertical-align: middle lines up an inline icon with the middle of the text beside it. A centring rule of thumb: Grid place-items for one child, Flexbox for a row of items, margin-inline: auto for page-width containers, text-align for text, positioning only for things that should overlap.

Explain it without notes

01

How would you centre a block horizontally, and why does it need a width?

02

Show two ways to centre an element both horizontally and vertically, and say when you'd choose each.

03

Why doesn't margin: auto centre vertically in normal flow, but does in a flex container?

04

Explain how top: 50%; left: 50%; transform: translate(-50%, -50%) centres a box.

Practice

01

Centre a 320px-wide .login card horizontally on the page, with 40px of space above it.

02

Centre an <h1> both ways in a full-screen .splash section.

03

Put a .play button exactly in the centre of a .video box whose size you don't know, on top of the video.

Trade-offs

  • ↔

    Grid and Flexbox centring is short and keeps the child in flow, but the parent changes its layout mode for all its children; positioning centres without affecting siblings but takes the child out of flow.

  • ↔

    translate(-50%, -50%) handles unknown sizes but can render on half pixels and conflicts with other transforms on the same element; inset: 0; margin: auto is crisp but needs a known or fit-content size.

Done when you can

  • I can centre text with text-align and a block with margin-inline: auto.

  • I can centre a child both ways with Grid or Flexbox.

  • I can centre a positioned box with inset: 0; margin: auto and with translate(-50%, -50%).

  • I know why vertical centring needs a parent with extra height.

  • I can choose the right centring method for a situation and explain why.