Command Palette

Search for a command to run...

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

Topic 8.5

Aligning in Grid

In one line

justify-* aligns along the row (inline) axis and align-* along the column (block) axis; -items and -self move items inside their grid areas, -content moves the whole set of tracks inside the container, and place-* sets both axes at once.

Think of it like this

Photos in a box of picture frames. Each photo can sit in the middle of its own frame, or in a corner, or be stretched to fill it: that's aligning an item inside its cell. Separately, if the frames don't fill the wall, you choose whether to bunch the whole group of frames in the middle of the wall or spread them out: that's aligning the tracks inside the container. Grid gives you separate controls for the two.

Words you'll meet

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

Inline axis
The direction text runs in a line (left to right in English). Grid's justify-* properties work along it.
Block axis
The direction paragraphs stack (top to bottom). Grid's align-* properties work along it.
`justify-items` / `align-items`
Set on the container: where every item sits inside its own area.
`justify-self` / `align-self`
Set on one item: overrides the container's -items value for that item.
`justify-content` / `align-content`
Set on the container: where the whole group of tracks sits when they're smaller than the container.
Stretch
Fill the whole area in that axis. The default for grid items without a fixed size or aspect ratio.
`place-*`
Shorthands that set the align value and then the justify value in one go.
`safe`
A keyword that stops centring from pushing an oversized item out of reach; it falls back to start.

Step by step

01Know which axis you're moving

Say it aloud: justify = along the row, align = down the column. Then ask: am I moving items inside their cells (-items, -self) or all the tracks inside the container (-content)?

Know which axis you're movingdiagram
Rendering diagram…

02Stop items stretching

By default each item fills its cell. align-items: start makes items only as tall as their content, sitting at the top of each cell; justify-items: start does the same for width.

style.csswhole filecss
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  align-items: start;
}

03Override one item

One item should sit at the bottom-right of its cell. place-self: end sets both axes to end.

style.csswhole filecss
.grid .note {
  place-self: end;
  /* align-self: end; justify-self: end; */
}

04Move the tracks

With fixed 80px columns in a wide container, there's spare space. justify-content: center puts the whole group in the middle; space-between pushes the first and last tracks to the edges.

style.csswhole filecss
.grid {
  display: grid;
  grid-template-columns: repeat(3, 80px);
  justify-content: space-between;
}

05Centre anything in one line

A grid with one item and place-items: center centres that item horizontally and vertically, whatever its size.

style.csswhole filecss
.hero {
  min-height: 300px;
  display: grid;
  place-items: center;
}

Try it yourself

  1. 1

    Predict before you align

    In the first example, add justify-self: end to .i3. Predict its new x and width: it can't stretch across any more, so it shrinks to its text width and moves to the right of its cell. Run and check which numbers changed.

  2. 2

    Try every content value

    In the second example, change justify-content to center, then space-around, then space-evenly. Predict item 4's x each time: center gives 150 (70px each side, so 70 + 80), space-evenly gives 173.33 (the 140px splits into three gaps of 46.67).

  3. 3

    Stretch the image

    In the third example, give the image's box place-items: stretch and the image width: 100%; height: 100%; object-fit: cover. Predict the logged size (200x120). Without object-fit it would distort.

Code & diagrams

Items inside their areas: -items and -self New tab

`i1` fills its whole 150×80 cell (stretch). `i2` is centred across its cell but still stretches vertically. `i3` stretches across but sits at the bottom. `i4` is centred both ways.

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

i1 x=0 y=0 150x80
i2 x=195 y=0 60x80
i3 x=0 y=130 150x30
i4 x=195 y=105 60x30
Tracks inside the container: -content New tab

The tracks use 160px of 300px width and 100px of 200px height. `space-between` puts the spare 140px between the two columns; `align-content: center` puts 50px above and below the rows. Try `place-content: end center`.

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

item 1 x=0 y=50
item 4 x=220 y=100
Centring, images and auto margins New tab

`place-items: center` centres the 80×40 box. The image is **not** stretched to 200×120: elements with an aspect ratio default to `start`. The auto margins soak up the free space on the left, top and bottom.

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

.center .dot x=60 y=40 80x40
img x=0 y=0 40x40
.push x=120 y=40 80x40
The six alignment propertiesdiagram
Rendering diagram…

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

justify-content with fr columns

On a grid with grid-template-columns: 1fr 1fr, set justify-content: center to centre the columns.

terminal
$ the page shows
── what you'll see ──
Nothing moves. The columns already fill the whole width.

Break #2

Centring something taller than its container

In a 200px-tall panel with grid-template-rows: 200px and align-items: center, put an item that is 400px tall.

terminal
$ the page shows
── what you'll see ──
The item sticks out 100px above the panel and 100px below it. Near the top of the page, the top part is off-screen and can't be reached.

Myth vs fact

Myth

justify-* always means horizontal and align-* vertical.

Fact

In grid, justify follows the inline axis and align the block axis. In a vertical writing mode (writing-mode: vertical-rl) they swap visually.

Myth

align-content and align-items do the same thing.

Fact

align-items moves each item inside its area. align-content moves the whole set of row tracks inside the container, and only when there is spare space.

Myth

place-items: center start centres horizontally.

Fact

The first value is align (block axis), so it centres vertically and puts items at the start horizontally.

Pro corner

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

  • ▸

    The keyword normal is the initial value of justify-items, align-items and the -self properties. For grid items it computes to stretch, except for boxes with a preferred aspect ratio (images, videos, aspect-ratio), where it acts like start so they aren't distorted.

  • ▸

    justify-self: stretch only affects items whose size in that axis is auto. A set width (or max-width) wins. Auto margins are resolved before alignment, so margin-left: auto overrides justify-self for that item.

  • ▸

    Baseline alignment (align-items: baseline, first baseline, last baseline) groups items in the same row and aligns their text baselines, which is handy for a row of labels and inputs of different font sizes.

  • ▸

    justify-content: space-* and gap add up: the visible gutter is gap plus the distributed space. Items that span several tracks also grow by the distributed space inside them, so with space-between a spanning item can become wider than you expect.

Remember this

  1. 1

    Grid has two axes. The inline axis runs the way text runs in a line (left to right in English): grid calls alignment along it **justify. The block axis runs the way paragraphs stack (top to bottom): alignment along it is align**. Unlike Flexbox, these never swap: in grid, justify is always along the row direction and align always down the columns, whatever you do with grid-auto-flow.

  2. 2

    **justify-items and align-items go on the container and set the default for every item: where each item sits inside its own grid area. justify-self and align-self go on one item** and override that default. The useful values are stretch (fill the area, the default for most items), start, end, center and, for align-*, baseline (line up the first line of text).

  3. 3

    Stretch is why grid items fill their cells by default: the default value normal behaves like stretch. Two exceptions: an item with a fixed width or height keeps that size in that axis, and images and other elements with a natural aspect ratio (like <img> and <video>) behave as start instead, so they keep their shape. When an item doesn't stretch, it shrinks to its content size and the -self value decides where in the area it sits. margin: auto on an item also works: auto margins soak up the spare space in its area and win over -self.

  4. 4

    **justify-content and align-content move the tracks, not the items. They only do something when the tracks add up to less** than the container, for example fixed 100px columns in a 500px grid (with any fr track the free space is already used up). Values: start, end, center, stretch (grows auto tracks), space-between, space-around and space-evenly. The space-* values make the visible gutters bigger than gap, because the extra space goes between tracks.

  5. 5

    The **place-* shorthands set both axes at once, with the align value first**: place-items: center (both centred), place-items: end start (align end, justify start). Likewise place-self and place-content. display: grid; place-items: center; on a box is the shortest way to centre one thing both ways (see Phase 6, Topic 6.5).

  6. 6

    When an item is bigger than its area, centring makes it overflow on both sides, and the part that sticks out past the top or left edge of a scroll container can never be scrolled to. The safe keyword (align-items: safe center) tells the browser to fall back to start when the item doesn't fit, so nothing is lost. Use it on centred content that might grow, like a modal's body.

Explain it without notes

01

Explain the difference between justify-items, justify-self and justify-content in grid.

02

Why do grid items fill their cells by default, and when don't they?

03

When does align-content have any effect?

04

What does place-items: end center do?

Practice

01

Centre a 120px by 60px button both ways inside a 100%-wide, 300px-tall hero section using grid.

02

A grid has three fixed 100px columns in a 600px container. Write the CSS to put equal space before, between and after the columns.

03

In a grid of cards where all items stretch, make only the .price item sit at the bottom-right corner of its cell.

Trade-offs

  • ↔

    Leaving items at stretch gives equal-height cards for free, but backgrounds then fill the whole cell; aligning to start keeps boxes tight to their content at the cost of ragged bottoms.

  • ↔

    place-items: center is the shortest centring, but it's unsafe for content that can grow taller than its container; add safe or use auto margins there.

Done when you can

  • I can tell which grid alignment properties work on the inline axis and which on the block axis.

  • I can align every item with justify-items/align-items and one item with -self.

  • I can move tracks with justify-content/align-content and say when that has an effect.

  • I can use place-items, place-self and place-content, putting the align value first.

  • I know why images don't stretch and how safe prevents lost content.