Vibe Engines
YouTube

Vibe Engines is free, interactive AI engineering & system design — runs in your browser. Pick a learning path

CSS Flexbox & Grid

Stop guessing at layout. The properties that actually center, distribute, and arrange things — flexbox for one dimension, grid for two.

Flexbox and grid are layout modes you switch on for a container with display; its direct children become flex or grid items. Flexbox lays items along one axis and sizes them from their content outward. Grid defines rows and columns first, then places items into the cells.

In flexbox, justify-* works along the main axis (set by flex-direction) and align-* across it. In grid, justify-* is always the row direction and align-* the column direction. Most real layouts use both: grid for the page, flex inside its pieces.

Flexbox (one axis)

Turn on
display: flex · direction: flex-direction: row | column
Along main axis
justify-content: center | space-between | space-around | flex-start
Across cross axis
align-items: center | stretch | flex-start | baseline
Wrap
flex-wrap: wrap · shorthand flex-flow: row wrap
Item grow/shrink
flex: 1 (grow) · flex: 0 0 200px (fixed basis)
Gap
gap: 1rem — spacing without margins
flex-direction: column
the main axis turns vertical, so justify-content now aligns top to bottom
align-content: center
spaces the lines of a wrapping container — no effect without flex-wrap: wrap
display: inline-flex
flex inside, inline outside — an icon-and-label button sitting in a line of text

Flex items

flex: 1
means 1 1 0%: items share the space equally, whatever their content
flex: auto
means 1 1 auto: grow from content size, so bigger content gets more room
flex: none
means 0 0 auto: never grow or shrink
flex: 2 vs flex: 1
widths split 2:1; bare flex-grow: 2 splits only the leftover space 2:1
flex-shrink: 0
stop an icon, avatar or sidebar from being squeezed narrower
min-width: 0
let an item shrink below its content — the fix for overflowing text, tables and pre
margin-left: auto
push this item, and everything after it, to the far end
align-self: flex-end
override align-items for one item
flex-basis: 200px
starting size along the main axis; beats width when both are set
order: -1
reorders visually only — tab and screen-reader order still follow the HTML

Grid (two axes)

Turn on
display: grid
Columns
grid-template-columns: 1fr 2fr · repeat: repeat(3, 1fr)
Responsive columns
repeat(auto-fit, minmax(200px, 1fr)) — the famous one
Gaps
gap: 1rem · row-gap / column-gap
Span cells
grid-column: span 2 · grid-row: 1 / 3
Named areas
grid-template-areas: "hd hd" "sb mn" then grid-area: hd
fr
a share of the space left over after fixed and content-sized tracks
minmax(0, 1fr)
a 1fr allowed below its content — stops one long word or table widening the column
auto-fill vs auto-fit
fill keeps empty tracks; fit collapses them, so the items stretch across the row
minmax(min(200px, 100%), 1fr)
the responsive pattern that also survives containers narrower than 200px

Grid placement & alignment

grid-column: 1 / -1
span from the first line to the last — a full-width row in the explicit grid
grid-auto-rows: minmax(100px, auto)
size for rows the grid creates on its own: at least 100px, taller if needed
grid-auto-flow: dense
backfill holes left by wide items — visual order then drifts from the HTML
grid-template-rows: subgrid
a nested grid reuses its parent’s tracks, so content lines up across cards
justify-items / align-items
position every item inside its cell; justify-self / align-self for one
place-content: center
center the whole set of tracks inside a larger grid container
"hd hd" ". mn"
in grid-template-areas a . is an empty cell; every area must be a rectangle

Centering (the eternal question)

Center anything (flex)
display:flex; justify-content:center; align-items:center
Center anything (grid)
display:grid; place-items:center
Center a block
margin-inline: auto with a set width
margin: auto (in flex or grid)
centers a child on both axes inside a flex or grid parent
inset: 0; margin: auto
centers an absolutely positioned box that has a width and height
text-align: center
centers inline content such as text and inline-blocks, not the block itself

Which one?

Flex
Content in a single row or column — navbars, toolbars, button rows.
Grid
Two-dimensional layouts — page skeletons, card galleries, forms.
Both
Grid for the page, flex inside each cell. They compose.
Content out vs layout in
flex sizes from the content outward; grid sets the tracks first, then fills them
gap, not margins
gap works in flex and grid and never doubles up or leaks at the edges

Recipes

Page layout: header, sidebar, main, footer

.page {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header header"
    "nav    main"
    "footer footer";
  min-height: 100vh;
}
header { grid-area: header; }
nav    { grid-area: nav; }
main   { grid-area: main; }
footer { grid-area: footer; }

@media (max-width: 700px) {
  .page {
    grid-template-columns: 1fr;
    grid-template-areas: "header" "nav" "main" "footer";
  }
}

The 1fr row pushes the footer to the bottom of short pages. minmax(0, 1fr) keeps a wide table or code block from widening the main column — give that child overflow-x: auto so it scrolls in place.

Responsive card grid with no media queries

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
  gap: 1rem;
}

Columns appear and disappear as the container resizes, and min(240px, 100%) stops a card overflowing a container narrower than 240px. Use auto-fill if a lone card should stay card-sized instead of stretching.

Navbar: logo left, links right, everything centered vertically

.nav {
  display: flex;
  align-items: center;
  gap: 1rem;
}
.nav .logo   { margin-right: auto; }  /* pushes everything after it to the right */
.nav .avatar { flex-shrink: 0; }      /* never squash the avatar */

An auto margin absorbs all the free space on its side, so no spacer elements are needed. Add flex-wrap: wrap if the links should drop to a second line on small screens.

Media object that never overflows

.media {
  display: flex;
  gap: 12px;
  align-items: flex-start;
}
.media img { flex: none; width: 48px; height: 48px; }
.media .body {
  flex: 1;
  min-width: 0;                /* allow shrinking below the longest word */
}
.media .body p { overflow-wrap: anywhere; }

Without min-width: 0 a flex item cannot shrink below its content, so one long URL pushes the text off the screen. To truncate a single line instead, use white-space: nowrap; overflow: hidden; text-overflow: ellipsis.

Line up titles and buttons across cards (subgrid)

.cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
}
.card {
  display: grid;
  grid-row: span 3;              /* title, body, button */
  grid-template-rows: subgrid;   /* share the parent's row tracks */
}

Every card’s title, body and button now share row heights, so the buttons align even when one card has more text. Subgrid works in all current major browsers.

Questions about CSS Flexbox & Grid Cheat Sheet

When should I use flexbox vs grid?

Use flexbox when items flow in one direction and their size should come from their content: navigation bars, toolbars, a row of buttons, an icon next to a label, or a list that wraps. Use grid when you want to control rows and columns together, so things line up in both directions: page layouts, card galleries, forms with aligned labels, dashboards. A useful test is whether you are laying out content, which suits flex, or a structure that content goes into, which suits grid. They nest freely, and most pages use grid for the overall layout and flexbox inside the components.

What is the difference between auto-fill and auto-fit in CSS grid?

Both create as many columns as fit when used in repeat() with minmax(), such as repeat(auto-fill, minmax(200px, 1fr)). The difference only appears when there are fewer items than columns. auto-fill keeps the empty column tracks, so the existing items stay at their minimum size and leave blank space at the end of the row. auto-fit collapses the empty tracks to zero, so the existing items stretch to fill the whole row. Choose auto-fit when a few items should fill the space, and auto-fill when cards should keep a consistent size.

Why is my flex item overflowing its container?

Flex items default to min-width: auto, which means they refuse to shrink below the width of their content. A long URL, a wide table, a pre block or an image with a fixed width therefore pushes the item, and the page, wider than the container. Set min-width: 0 on the flex item, or overflow: hidden, to let it shrink, and then deal with the content itself using overflow-wrap: anywhere, text-overflow: ellipsis or overflow-x: auto. The same issue appears in grid as a 1fr column blowing out, and minmax(0, 1fr) fixes it.

How do I center a div horizontally and vertically?

The shortest modern way is to make the parent a grid and center its content: display: grid together with place-items: center. With flexbox, set display: flex, justify-content: center and align-items: center on the parent. Either way, the parent needs a height for vertical centering to be visible, such as min-height: 100vh for a full-screen layout. Inside a flex or grid parent, margin: auto on the child also centers it on both axes. To center only horizontally, a block with a set width can use margin-inline: auto.