Skip to content

Layout: flexbox, grid and container queries

Flex shares one axis's spare space by ratio; grid subtracts fixed tracks and gaps before fr; container queries follow a component's box.

Predict first

Before you read: predict

The candidate's question-card footer holds a Flag group and an Answer group.

.footer { display: flex; width: 600px; }
.flag   { flex: 1 1 200px; }
.answer { flex: 2 1 100px; }
<div class="footer"><div class="flag"></div><div class="answer"></div></div>

Wrong or E → FULL. A correct tap with a vague why → TARGETED on steps 2–4. FAST needs basis-first and grow-shares-free-space.

What widths does Chromium render for the two groups?

Pick one

The 30-second version

Flexbox works along one axis: items start at their flex-basis, then flex-grow shares the leftover space in ratio, or flex-shrink removes overflow. Grid sizes tracks first: fixed tracks and gaps, then fr splits the rest; items auto-place into free cells. A container query reads its container's width, not the viewport. z-index competes only within one stacking context.

Flex shares one axis's spare space by ratio; grid subtracts fixed tracks and gaps before fr; container queries follow a component's box.

How it works

Step 1 of 12

One axis or two. Flexbox lays items along one main axis; grid draws rows and columns on the container, then places items in them.

Analogy: A storeroom's modular cubby shelving

The selected image shows a man on a stool setting a blue jar into a long, curving run of cubbies along the wall. In front stands a lower cube cabinet ruled into a grid, where some compartments span two cells.

In the storeroom In CSS layout
each cubby along the wall run has its own starting width, and only the run's spare length is shared out flex-basis, then flex-grow sharing the free space (steps 2–3)
a cubby holding a wide object cannot be squeezed narrower than that object the automatic minimum size (step 5)
the cabinet's side panels and dividers are measured off before the compartments share what remains fixed tracks and gaps, then fr (step 6)
goods go into the next free compartment in order; a two-cell box that does not fit leaves a gap auto-placement and holes (step 8)
a cabinet built to fit its alcove, not to the size of the room a container query, not a media query (steps 9–10)

In real terms: both layout systems size from rules declared on the container, but flex starts from each item's basis while grid starts from the track list.

Breaks down when: the storeroom has no depth order. Stacking contexts (steps 11–12) have no shelf equivalent, and shelving has no rule weighting a shrink by each cubby's width (step 4).

Contrasting case: one row of buttons that only needs spacing. No track system is needed; flex with gap places them.

Examples, run for real

4.1 EXH-2000: one card, a wide pane and a narrow drawer

The question card sits in a 760 px pane on the candidate's desktop and in a 320 px drawer in the proctor's split view, on a 1440 px screen. Its two-column layout keyed on a viewport media query, so the drawer copy also went wide and overflowed. MR !2300 makes each slot a query container and keys the layout on the slot's width.

/* before */ @media (min-width: 1024px) { .card { grid-template-columns: minmax(240px, 1fr) minmax(240px, 1fr); } }
/* after  */ .slot { container-type: inline-size; }
             @container (min-width: 560px) { .card { grid-template-columns: minmax(240px, 1fr) minmax(240px, 1fr); } }
viewport media query (before MR !2300) | 760 px slot: 2 col | 320 px slot: 2 col, overflows
container query (MR !2300)           | 760 px slot: 2 col | 320 px slot: 1 col

A media query reads the screen, which is the same for both copies. The container query reads each slot, so one rule serves both places (step 9).

4.2 Flex basis decides what is shared

Three filter tabs, "All", "In stock" and "Ships tomorrow", share a 600 px bar with equal flex-grow. Only the basis changes.

tabs flex: 1    | widths 200 / 200 / 200
tabs flex: auto | widths 153 / 197 / 250

flex: 1 sets the basis to 0, so all 600 px are spare and split equally. flex: auto starts each tab at its content width, and only the remainder is shared, so longer labels stay wider (steps 2–3).

4.3 Grid sizes tracks, then places items

A checkout summary grid uses grid-template-columns: 200px 1fr 1fr in 800 px with no gap, and holds four unpositioned items.

grid 200px 1fr 1fr in 800 px | widths 200 / 300 / 300 | item 4 at column 1, row 2

The fixed track takes 200 px, and the two fr tracks split the remaining 600 px (step 6). The fourth item finds no free cell in row 1, so auto-placement starts row 2 (step 8).

Picture it

A grey-haired man on a stool places a blue jar into a long, curving run of cubbies, beside a lower cube cabinet whose compartments form a grid, some spanning two cells.
An illustration to help it stick. The mechanism is in the sections above.

Try it

Answer first, then check. Nothing is saved.

Question 1 of 6

In this checkout order row, a long product code pushes the price past the row's right edge.

.row   { display: flex; width: 320px; }
.name  { flex: 1; }
.code  { white-space: nowrap; }
.price { flex: 0 0 80px; }
<div class="row"><div class="name"><span class="code">SKU-TRAIL-RUNNER-GTX-WIDE-EU44</span></div><div class="price">€89.00</div></div>

Which change keeps the price inside the row, on the same line as the name?

Pick one

Question 2 of 6

A checkout review grid lays out an icon, the item details and the delivery options.

.grid { display: grid; width: 720px; grid-template-columns: 120px 1fr 2fr; gap: 30px; }
<div class="grid"><div></div><div></div><div></div></div>

What width does Chromium render for the third column?

Pick one

Question 3 of 6

The order card sits in a 300 px summary column inside a page section, and the same markup appears twice, in an 800 px section and a 400 px one. The card should show two columns in the 800 px copy and one column in the 400 px copy. Today it shows one column in both.

.summary { container: slot / inline-size; width: 300px; }
.section { container: wrap / inline-size; }
.card    { display: grid; grid-template-columns: 1fr; }
@container (min-width: 500px) { .card { grid-template-columns: 1fr 1fr; } }
<div class="section" style="width:800px"><div class="summary"><div class="card"><p>Items</p><p>Total</p></div></div></div>
<div class="section" style="width:400px"><div class="summary"><div class="card"><p>Items</p><p>Total</p></div></div></div>

Which change meets that?

Pick one

Question 4 of 6

A checkout's delivery-slot menu opens upward from the content area, but where it meets the header, the header covers it.

.header  { position: relative; z-index: 10; height: 60px; background: #eee; }
.content { position: relative; z-index: 1; }
.menu    { position: absolute; top: -40px; left: 0; width: 200px; height: 120px; z-index: 9999; background: #cfc; }
<div class="header">Header</div><div class="content"><div class="menu">Delivery slots</div></div>

Which change puts the menu on top there, without moving the menu?

Pick one

Question 5 of 6

A checkout lists its payment methods as tiles in a 900 px container. Each tile must be at least 160 px wide, and tiles in later rows must line up with the columns above. This week one market has only two methods, and those two tiles should share the full row.

.methods { width: 900px; gap: 10px; }
<div class="methods"><div class="tile">Card</div><div class="tile">Wallet</div></div>
<div class="methods"><div class="tile">Card</div><div class="tile">Wallet</div><div class="tile">Bank</div><div class="tile">Gift</div><div class="tile">Later</div><div class="tile">Cash</div><div class="tile">Voucher</div></div>

Which declarations meet all of that?

Pick one

Question 6 of 6

A checkout's add-on grid lists five add-ons in order, and gift wrap is two columns wide.

.extras { display: grid; grid-template-columns: repeat(3, 100px); grid-auto-flow: dense; }
.wide   { grid-column: span 2; }
<div class="extras"><div>Insurance</div><div>Express</div><div class="wide">Gift wrap</div><div>Card</div><div>Bag</div></div>

In which cells does Chromium place Card and Bag?

Pick one

Go deeper

Pro tips
  1. Read the measured boxes before changing numbers. Chromium's Elements panel marks flex and grid containers with a badge that toggles an overlay of tracks, gaps and item boxes. Compare that overlay with the sizes you expected before editing a basis, a track or a breakpoint. (Not executed here; DevTools UI.)
  2. Size type to the container, too. Container query units such as cqi (1% of the query container's inline size) let a heading scale with its slot instead of the screen. Verify: font-size: 10cqi inside a 320 px inline-size container computed to 32px.
Source
  • W3C, CSS Flexible Box Layout Module Level 1: https://www.w3.org/TR/css-flexbox-1/ · read 2026-10-01 · sources/css-flexbox-1.txt (SHA-256 b0e3b097bc6db0688d4712968c290cda280f8f750eb998bc358c28df490ff3f5). "A flex container distributes free space to its items (proportional to their flex grow factor) to fill the container, or shrinks them (proportional to their flex shrink factor) to prevent overflow." Its automatic-minimum rule supports step 5. Steps 1–5. As of 2026-10-01.
  • MDN, Controlling ratios of flex items along the main axis: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_flexible_box_layout/Controlling_ratios_of_flex_items_along_the_main_axis · read 2026-10-01 · sources/mdn-flex-ratios.txt (SHA-256 5e62e24a3d807d90b7cabac4c19f2d0ac54f6271cc80a8f56031534a552f838a). "flex-basis: What is the size of the item before growing and shrinking happens?" Steps 2–4. As of 2026-10-01.
  • W3C, CSS Grid Layout Module Level 2: https://www.w3.org/TR/css-grid-2/ · read 2026-10-01 · sources/css-grid-2.txt (SHA-256 05aa64853c4428146973943b35caf121e44c1076bdf5b8c29f8896dba9b778e2). The fr unit "represents a fraction of the leftover space in the grid container"; dense "attempts to fill in holes earlier in the grid if smaller items come up later". Steps 6 and 8. As of 2026-10-01.
  • MDN, CSS grid layout: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout · read 2026-10-01 · sources/mdn-grid-layout.txt (SHA-256 93ec0ba75628beac79b21696ca5bd69b120deed1157bf820ba89d0101dd33ebc); Auto-placement in grid layout: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout/Auto-placement_in_grid_layout · sources/mdn-grid-auto-placement.txt (SHA-256 fc1911e25c543912973bc9657ac037ba8c26e52fdd3bcc4118a7bd15f2798a26); repeat(): https://developer.mozilla.org/en-US/docs/Web/CSS/repeat · sources/mdn-repeat.txt (SHA-256 9f2ad2864e8fc795f86c9da24f12f9ed2e64e6cb3888dd834ae3b6599e161a07): "The auto-fit value behaves the same as auto-fill, except that after placing the grid items any empty repeated tracks are collapsed." Steps 6–8. As of 2026-10-01.
  • W3C, CSS Conditional Rules / Containment Level 3: https://www.w3.org/TR/css-contain-3/ · read 2026-10-01 · sources/css-contain-3.txt (SHA-256 7e6b410172bfecf8b5fcccca2c5d6862ea87b81f20c34cd508934199f5373ec7). "The query container for each axis is the nearest ancestor container that accepts container size queries on that axis." Steps 9–10. As of 2026-10-01.
  • MDN, CSS container queries: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_containment/Container_queries · read 2026-10-01 · sources/mdn-container-queries.txt (SHA-256 e0227dfdc592c32ca049a63a6cd088321ca669fa0536e9c0617053a621f5c62b). "you need to declare a containment context on an element so that the browser knows you might want to query the dimensions of this container later." Steps 9–10 and pro tip 2. As of 2026-10-01.
  • MDN, Stacking context: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_positioned_layout/Understanding_z-index/Stacking_context · read 2026-10-01 · sources/mdn-stacking-context.txt (SHA-256 c632fb4acf37406e11097640d571d2648cd04eafadddeb365b1fde3c3060b0bc). "Importantly, the z-index values of its child stacking contexts only have meaning within its parent's stacking context." Steps 11–12. As of 2026-10-01.
  • Each source file starts with its URL, the date read, the HTTP status, Via: direct (curl, no reader proxy) and the SHA-256 of the saved body.

Checked against the tools and docs as of 2026-10-01.