What is the difference between Flexbox and CSS Grid?
Flexbox is one-dimensional: items sit in one row or column and their content sets their size. Grid is two-dimensional: you define rows and columns and place items in them, so they line up both ways. Use grid for the page and card grids and flex inside each card. More in CSS Grid.
What is the fr unit in CSS Grid?
fris a share of the free space in the grid: what is left after fixed tracks and gaps.HTML<style> .grid { display: grid; grid-template-columns: 200px 1fr 2fr; width: 500px; background: #e5e7eb; } .grid div { background: #2563eb; color: white; padding: 8px 0; border-right: 2px solid white; } </style> <div class="grid"><div>200px</div><div>1fr</div><div>2fr</div></div> <script> for (const el of document.querySelectorAll('.grid div')) el.textContent += ' = ' + el.offsetWidth + 'px'; </script>200px is fixed and 300px is free, so
1fris 100px and2fris 200px. Unlike33.33%columns,repeat(3, 1fr)subtracts thegapfirst, so the gaps never cause overflow.What is the difference between auto-fill and auto-fit in repeat()?
Both create as many columns as fit, so
repeat(auto-fill, minmax(120px, 1fr))is a responsive grid with no media queries. With fewer items than columns,auto-fillkeeps the empty columns andauto-fitcollapses them, so the items stretch to fill the row.HTML<style> .g { display: grid; gap: 8px; width: 520px; background: #e5e7eb; padding: 8px; margin-bottom: 8px; } .fill { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); } .fit { grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); } .g div { background: #2563eb; color: white; padding: 10px; } </style> <div class="g fill"><div>auto-fill</div><div>2</div></div> <div class="g fit"><div>auto-fit</div><div>2</div></div>How do grid-template-areas work?
Name each child's region with
grid-area, then draw the layout as strings on the container: one string per row,.for an empty cell. Each area must be a rectangle.HTML<style> .page { display: grid; gap: 6px; height: 220px; grid-template-columns: 120px 1fr; grid-template-rows: auto 1fr auto; grid-template-areas: "header header" "side main" "footer footer"; } .page > * { background: #2563eb; color: white; padding: 8px; } header { grid-area: header; } aside { grid-area: side; } main { grid-area: main; } footer { grid-area: footer; } </style> <div class="page"><header>header</header><aside>side</aside><main>main</main><footer>footer</footer></div>A media query can redefine only
grid-template-areas, and the children follow with no HTML change.What is the difference between the explicit and the implicit grid?
The explicit grid is the tracks you define with
grid-template-columnsandgrid-template-rows. Extra items get tracks the browser adds, the implicit grid, sized bygrid-auto-rowsandgrid-auto-columns(defaultauto)..gallery { display: grid; grid-template-columns: repeat(3, 1fr); /* explicit: 3 columns */ grid-auto-rows: 120px; /* every implicit row is 120px */ grid-auto-flow: row dense; /* backfill holes left by big items */ } .gallery .wide { grid-column: span 2; }densebackfills holes with later items, so visual order stops matching the DOM: fine for a gallery, not for text.Why does a 1fr column grow wider than its share?
Because
1frmeansminmax(auto, 1fr): its minimum is the content's minimum width, so a long word or a wide table forces the track wider.minmax(0, 1fr)lets it shrink; then handle the content withoverflow-wrap: anywhereoroverflow: auto.HTML<style> .g { display: grid; gap: 8px; width: 300px; border: 1px solid #9ca3af; margin-bottom: 8px; } .one { grid-template-columns: 1fr 1fr; } .two { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } .g div { background: #dbeafe; padding: 4px; } .two div { overflow-wrap: anywhere; } </style> <div class="g one"><div>Pneumonoultramicroscopicsilicovolcanoconiosis</div><div>short</div></div> <div class="g two"><div>Pneumonoultramicroscopicsilicovolcanoconiosis</div><div>short</div></div>It is the grid twin of the flexbox
min-width: 0bug.What is subgrid and what problem does it solve?
grid-template-rows: subgrid(or columns) makes a nested grid reuse its parent's tracks, so titles and buttons line up across cards even when one title wraps. It works in Chrome 117+, Firefox 71+ and Safari 16+ (see MDN subgrid).HTML<style> .cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0 10px; } .card { display: grid; grid-row: span 3; grid-template-rows: subgrid; gap: 6px; border: 1px solid #9ca3af; border-radius: 8px; padding: 8px; margin-bottom: 8px; } .card h4 { margin: 0; } .card p { margin: 0; } button { align-self: end; } </style> <div class="cards"> <div class="card"><h4>Basic</h4><p>Short text.</p><button>Buy</button></div> <div class="card"><h4>A much longer plan name that wraps</h4><p>Text.</p><button>Buy</button></div> <div class="card"><h4>Pro</h4><p>A longer description that takes more lines than the others.</p><button>Buy</button></div> </div>Each card spans three parent rows, so the tallest title sets every card's title row.
How do you make a grid item span several columns or rows?
Use
grid-columnandgrid-rowwith line numbers orspan. Lines are numbered from 1, and negative numbers count from the end, sogrid-column: 1 / -1spans every column.HTML<style> .g { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; width: 360px; } .g div { background: #2563eb; color: white; padding: 10px; } .tall { grid-row: span 2; } .wide { grid-column: span 2; } .full { grid-column: 1 / -1; } </style> <div class="g"> <div class="tall">span 2 rows</div><div class="wide">span 2 columns</div> <div>3</div><div>4</div> <div class="full">1 / -1: full width</div> </div>-1is the last line of the explicit grid, so it never reaches implicit columns.What is the difference between justify-content, justify-items and justify-self in Grid?
justify-contentmoves the whole set of tracks inside the container when they are narrower than it.justify-itemsaligns every item inside its own cell along the row, andjustify-selfdoes it for one item, overridingjustify-items. Thealign-*versions work on the column axis, andplace-*sets both.HTML<style> .g { display: grid; grid-template-columns: 100px 100px; gap: 6px; width: 320px; padding: 6px; background: #e5e7eb; justify-content: center; justify-items: start; } .g div { background: #2563eb; color: white; padding: 6px; } .end { justify-self: end; } </style> <div class="g"><div>start</div><div class="end">end</div><div>start</div><div>start</div></div>The two 100px columns sit centered in the box, and each item is only as wide as its text, at the start of its cell, except the one set to
end.How do you overlap elements with CSS Grid instead of position: absolute?
Put them in the same cell:
grid-area: 1 / 1on every child stacks them, later ones in front (or ordered byz-index). Unlike absolute positioning they stay in the flow, so the container grows to fit the tallest layer.HTML<style> .hero { display: grid; width: 300px; } .hero > * { grid-area: 1 / 1; } .bg { min-height: 100px; background: linear-gradient(135deg, #2563eb, #7c3aed); } .text { align-self: end; margin: 0; padding: 12px; color: white; } </style> <div class="hero"> <div class="bg"></div> <p class="text">Text over the background. Add more lines and the whole block grows with them.</p> </div>It is the usual way to put a caption over an image without fixing heights.
CSS Grid Interview Questions
Grid versus Flexbox, fr units, auto-fill vs auto-fit, template areas and track sizing.
10 questions