CSS Grid — `min-width: auto` Breaks Your fr Units
Grid items overflow containers because fr units ignore min-width:auto defaults.
20+ years shipping production JavaScript and front-end systems at scale. Drawn from code that ran under real load.
- ✓Solid grasp of fundamentals
- ✓Comfortable reading code examples
- ✓Basic production concepts
- CSS Grid defines a two-dimensional layout system where you create columns and rows, then place items into cells.
- Grid container: element with
display: grid; Grid items: direct children. - Track sizing:
grid-template-columns,grid-template-rowsacceptpx,fr,%,auto,minmax(), etc. - Item placement:
grid-column,grid-rowusing line numbers or spans. - Performance: Grid avoids layout reflows for most changes — browser caches the grid structure.
- Production pitfall: Implicit grid auto-generates rows/columns with
autosize, often causing overflow when content is larger than expected. - Biggest mistake: Forgetting to set
min-height: 0on grid items when using1frinside nested grids — causes item to grow beyond container.
CSS Grid is a two-dimensional layout system that lets you control both columns and rows simultaneously. Unlike Flexbox, which is one-dimensional, Grid gives you a graph-paper-like grid where you can place items precisely. It's the first CSS layout system designed for complex page layouts, not just documents.
Imagine you're arranging furniture in a room. You first draw a floor plan on graph paper — marking out rows and columns — then you decide which piece of furniture goes in which square. CSS Grid is exactly that floor plan for your webpage. You define the 'grid' (the columns and rows), then you place your content (the furniture) into it. Unlike older CSS methods that stack things like a single filing cabinet, Grid lets you control both directions — horizontal AND vertical — at the same time.
| Chrome | Firefox | Safari | Edge |
|---|---|---|---|
| ✓ | ✓ | ✓ | ✓ |
You've hit the same wall too many times. It's time to stop fighting floats. CSS Grid was built for this.
Every web developer hits the same wall: you have a beautiful design mockup with a sidebar, a hero image, a content area, and a footer — and you spend three hours fighting floats, clearfixes, and position hacks trying to make it real. That wall exists because CSS was originally designed for documents, not applications. Modern UIs need two-dimensional control, and for the longest time, we were building them with one-dimensional tools. CSS Grid was built specifically to tear that wall down. It's the first CSS layout system that was designed with complex, two-dimensional layouts in mind from day one — not bolted on as an afterthought.
Here's the catch: senior engineers know that Grid's raw power comes with sharp edges. The fr unit looks simple until your items overflow. Implicit tracks behave differently than you expect. And grid-auto-flow: dense can silently break your tab order. This guide doesn't just repeat the docs — it walks through the production failures that surprise even experienced developers and shows you how to avoid them.
What is CSS Grid?
CSS Grid is a two-dimensional layout system that lets you control both columns and rows simultaneously. Unlike Flexbox, which is one-dimensional, Grid gives you a graph-paper-like grid where you can place items precisely. It's the first CSS layout system designed for complex page layouts, not just documents.
<div class="container" style="display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px;"> <div>1</div> <div>2</div> <div>3</div> </div>
display: grid becomes a grid container. Its direct children become grid items. That's it. No extra wrappers needed.-ms- prefix.Defining the Grid: Columns, Rows & Track Sizing
Every CSS Grid starts with a container element set to display: grid. Then you define the column and row tracks using grid-template-columns and grid-template-rows. You can use absolute units (px, em), flexible units (fr — fraction of free space), or content-based sizing (auto, min-content, max-content). The function combines minimum and maximum sizes — essential for responsive layouts without media queries. For example, minmax()grid-template-columns: repeat(3, minmax(200px, 1fr)) creates three columns that each shrink to 200px before wrapping (with auto-fill) or staying flexible.
.container {
display: grid;
grid-template-columns: 1fr 2fr 1fr;
grid-template-rows: auto 1fr auto;
gap: 16px;
}grid-template-columns and grid-template-rows as drawing the rows and columns on graph paper before placing any content.- Each value creates one track (column or row) in order.
1frmeans 'give this track one fraction of the remaining space' — tracks with more fr get proportionally bigger.autosizes to fit the content — like a wildcard.minmax(200px, 1fr)ensures the track never goes below 200px but grows up to fill space.- Implicit tracks (automatic) default to
auto— you'll see them later.
1fr column. The column won't shrink below 300px. Layout break.min-width: auto on grid items.min-width: 0 on the item.fr unit is a fraction of free space — not a percentage.auto size.min-width: 0 on items when using fr to avoid overflow.px, em, or % — no flexibility needed.fr units: 1fr 3fr 1fr for sidebar-main-sidebar.repeat(auto-fill, minmax(250px, 1fr)) — responsive without media queries.grid-template-rows: auto 1fr auto — classic holy grail.Placing Grid Items with Line Numbers and Span
Once you have a grid, every direct child becomes a grid item. By default, items auto-place one per cell, left-to-right, top-to-bottom. But you can explicitly place items using grid-column and grid-row. The syntax is grid-column: start-line / end-line. Lines are numbered from 1 at the top-left. Negative numbers count from the end (-1 is the last line). To span multiple tracks, use the span keyword: grid-column: span 2. You can also use named lines (defined in grid-template-columns). Overlapping items are allowed — create layered layouts by setting z-index. When items overlap, the browser renders them in DOM order by default.
.layout {
display: grid;
grid-template-columns: 1fr 3fr;
grid-template-rows: auto 1fr auto;
gap: 12px;
}
.header { grid-column: 1 / -1; }
.sidebar { grid-row: 2 / 3; }
.main { grid-column: 2 / 3; }
.footer { grid-column: 1 / -1; }grid-column: 1 / span 2 means start at line 1 and cover the next two tracks (columns 1 and 2). grid-column: 1 / 3 is the same. Many devs write grid-column: 0 / 2 — that's invalid and the property is ignored.order property only if semantics allow.grid-column and grid-row on structural elements.grid-template-columns and let items flow in.grid-column: 1 / 2; grid-row: 1 / 2.Named Grid Areas: Cleaner Layouts
When you have a well-defined layout, naming grid areas makes your CSS read like a blueprint. Use grid-template-areas on the container with a visual grid of strings. Each string represents one row, each word represents a cell. Use a period . to leave a cell empty. Then assign each item to an area with grid-area: name. This approach is much easier to maintain than line numbers — you can rearrange the entire layout by swapping words in the template.
.page {
display: grid;
grid-template-columns: 200px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }@media queries to redefine grid-template-areas. For mobile, change to a single column: "header" "main" "sidebar" "footer". No need to move items — just update the container's template.grid-template-areas is the most readable way to define layouts...Auto-Placement and the Implicit Grid
When you define only columns but not rows, or the number of items exceeds defined tracks, the browser creates implicit tracks — auto-generated rows or columns. The sizing of these implicit tracks is controlled by grid-auto-rows and grid-auto-columns. By default, grid-auto-rows: auto sizes rows to fit content, which can cause uneven heights in a grid of cards. Set grid-auto-rows: 1fr to force equal height, but beware of overflow again. grid-auto-flow controls the placement direction: row (default, fill left-to-right then wrap), column (top-to-bottom then wrap), dense (pack items to fill gaps — but can reorder DOM).
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-auto-rows: 1fr; /* all cards same height */
gap: 16px;
}
.card {
/* items placed automatically */
}grid-auto-flow: dense reorders items to fill gaps in the grid. This improves visual density but breaks tab order on the page. Screen readers follow DOM order, not visual order. Never use dense for content that needs logical reading order (e.g., articles, forms).auto height — if one card has more text, that row stretches.grid-auto-rows: 1fr but add min-height: 0 to each card or use align-items: stretch (default).overflow: hidden and height: 100%.grid-auto-rows.dense packing fills gaps but reorders DOM — use only for decorative content.1fr on grid-auto-rows and handle overflow.grid-auto-rows: 1fr + min-height: 0 on items.grid-auto-rows: 200px (fixed height) + object-fit: cover on images.grid-auto-flow: row — no dense packing.grid-auto-flow: dense — but only if visual density trumps accessibility.Alignment: Items, Content, and Tracks
CSS Grid provides powerful alignment along both axes. On the container, justify-items (horizontal) and align-items (vertical) align all items within their cells. Default is stretch — items fill the cell. Use start, end, center to change. justify-content and align-content align the entire grid within the container — useful when the total grid size is smaller than the container (e.g., content tracks smaller than container height). For individual items, use justify-self and align-self to override the container setting. These properties work exactly the same as in Flexbox but apply to the cell, not the main axis.
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
align-items: center; /* vertical center within cells */
justify-items: start; /* horizontal left-align */
height: 400px;
}
.special-item {
align-self: end; /* override for this item */
justify-self: stretch;
}justify-items: horizontal alignment of items within cells.align-items: vertical alignment of items within cells.justify-content: horizontal alignment of the whole grid within the container.align-content: vertical alignment of the whole grid within the container.place-items: center center;sets both justify and align in one property.
align-items: stretch (default) works well unless you have fixed-height rows.grid-template-rows: 200px 200px, items inside are stretched to 200px — if content is taller, it overflows.align-items: start if you want items to size to content, or use min-height: 0 and overflow: auto on items.place-items is shorthand for both axes — use it cleanly.Responsive Grids Without Media Queries
One of CSS Grid's greatest features is creating responsive layouts that adapt to available space without a single @media rule. Use repeat(auto-fill, minmax(250px, 1fr)) — now the number of columns depends on the container width. auto-fill creates as many tracks as possible, even if some are empty. auto-fit collapses empty tracks, allowing items to stretch wider. For a card layout that goes from 1 column on mobile to 4 on desktop, just set minmax(250px, 1fr) — the browser does the math. Combine with grid-auto-rows to keep cards equal height.
.responsive-cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 16px;
padding: 16px;
}
/* No media queries needed */auto-fill keeps empty column tracks — if container is 600px and minmax is 250px, you get 2 columns + leftover space (maybe 100px). auto-fit collapses leftover space into the existing columns, making them wider. Use auto-fit when you want items to grow, auto-fill when you want strict column widths.minmax() are amazing, but they can cause unexpected wrapping.@media breakpoint to increase the minmax minimum at larger screens for smoother transitions.repeat(auto-fill, minmax(250px, 1fr)) is the single most powerful responsive pattern.auto-fit collapses empty tracks, auto-fill preserves them — know the difference.Grid Layout Performance and Browser Rendering
CSS Grid is highly optimised in modern browsers, but it's not free. When you change grid properties like grid-template-columns, the browser must recalculate the entire grid layout, which triggers a layout reflow. Unlike Flexbox, where a single item change may only affect its immediate siblings, a grid change can affect all items in the grid. For static grids (those that don't change dynamically), Grid performs better than older methods because the browser precomputes track sizes. However, if you programmatically add or remove items in a grid with auto-fill or auto-fit, the browser re-evaluates the number of columns, which can be expensive on large grids. The best practice: avoid changing grid properties in rapid succession (e.g., during animations or scroll events). If you need to animate item positions, use transform or opacity instead of changing grid placement.
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
transition: grid-template-columns 0.3s; /* Not recommended — causes full reflow */
}
/* Better: animate individual items with transforms */
.grid-item {
transition: transform 0.3s;
}
.grid-item:hover {
transform: scale(1.05);
}grid-template-columns on a grid with hundreds of cards can freeze the UI for hundreds of milliseconds.Subgrid and Nested Grid Alignment
Subgrid lets a grid item that is itself a grid container inherit the track definitions from its parent. This means nested items can align with the parent's grid lines. It's ideal for repeating patterns like product cards where you want the title of each card to align horizontally across rows, or for tabular data where headers and cells should align. However, subgrid is only supported in Firefox and Safari as of 2026. Chrome has it behind a flag. For production use, you may need a fallback using explicit line numbers and matching track sizes. The subgrid value is applied to grid-template-rows or grid-template-columns on a nested grid.
.parent-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: auto 1fr auto;
}
.card {
display: grid;
grid-template-rows: subgrid; /* inherits parent's row tracks */
grid-row: span 1; /* each card occupies one row */
}- Subgrid inherits the size of the parent's track, not the content of the nested item.
- You can subgrid columns, rows, or both.
- The nested grid's gap is applied on top of the parent's gap.
- Subgrid does not work with non-rectangular shapes (like spanning partial tracks).
grid-template-rows: repeat(3, minmax(0, 1fr)) and hope content doesn't overflow.Grid and Accessibility: Source Order vs Visual Order
One of the most overlooked patterns when using CSS Grid is the impact on accessibility. Screen readers and keyboard navigation follow the DOM order, not the visual order. When you use explicit placement or grid-auto-flow: dense, you can create a visual layout that is completely different from the source order. This breaks tab order for keyboard users and confuses screen reader users. The rule: if the content has a meaningful reading order (articles, forms, navigation), keep the DOM order matching the visual order. Use Grid's placement only for decorative reordering or when you've tested with a screen reader.
<div class="card-grid"> <!-- Source order matches visual order: left to right, top to bottom --> <article class="card">First story</article> <article class="card">Second story</article> <article class="card">Third story</article> </div>
grid-auto-flow: dense reorders items to fill gaps — it's the #1 grid property that breaks tab order. Never use it on content that has a logical sequence. For photo galleries without captions, it's acceptable.Grid Debugging: Why Your Items Keep Disappearing
You've defined your grid, placed your items, and one of them just vanishes. No error. No clue. Here's what's happening: you accidentally overlapped two items without explicit layering, or your grid item spilled into negative space due to a fractional unit calculation. Grid doesn't warn you. It just forces the item off-screen or hides it behind another. The fix: always check your grid lines with browser dev tools. Verify that your grid-column and grid-row values map to existing lines. If you use grid-template-columns: 1fr 2fr 1fr, you have four lines (1, 2, 3, 4). Placing an item from line 3 to line 5 creates an implicit track, often with zero or negative size. Use minmax() to guarantee minimum track sizes. Never assume grids fail gracefully—they fail invisibly.
// io.thecodeforge // Implicit track trap: item placed beyond defined lines .div-container { display: grid; grid-template-columns: 1fr 2fr 1fr; /* 4 lines only */ } .item-overreach { grid-column: 3 / 5; /* line 5 does not exist -> implicit track */ /* Browser creates a zero-width column -> item invisible */ } // Fix: define extra columns or use span .item-fixed { grid-column: 3 / span 1; /* stays within bounds */ }
The Holy Grail Layout: A Grid Without Abstractions
Every junior wants the 'holy grail'—header, footer, two sidebars, main content. They reach for frameworks. Real senior engineers write 10 lines of CSS. Grid offers it natively. Define your template with grid-template-areas. Assign items to named areas. That's it. No floats. No hacks. No flex containers inside flex containers. The layout is responsive by default because you can swap areas in a media query. Why does this work? Grid's two-dimensional nature handles both row and column alignment simultaneously. Your header spans full width. Your footer does too. The sidebars and main sit in a middle row. No JavaScript. No overrides. Just declaration. This pattern handles 90% of application shells. Learn it. Teach it. Ship it.
// io.thecodeforge // Minimal holy grail layout using grid-template-areas .app-shell { display: grid; grid-template-areas: "header header header" "nav main aside" "footer footer footer"; grid-template-columns: 200px 1fr 200px; grid-template-rows: auto 1fr auto; min-height: 100vh; } .header { grid-area: header; } .nav { grid-area: nav; } .main { grid-area: main; } .aside { grid-area: aside; } .footer { grid-area: footer; }
Grid vs Flexbox: When the Wrong Tool Burns You
You see a row of cards. You reach for flexbox. Works fine. Then you need a second row that aligns vertically with the first. Flexbox can't do that natively—it only knows one axis. You hack with min-heights and negative margins. Stop. Grid handles two-dimensional alignment out of the box. If your layout needs both row and column alignment, grid is the only correct tool. Flexbox is for one-dimensional flows: a toolbar, a nav bar, inline components. Grid is for page structure: dashboards, galleries, article layouts. The failure mode of forcing flexbox into 2D is unpredictable wrapping, misaligned columns, and brittle CSS that breaks when content changes. Grid gives you explicit track sizes. Your columns stay aligned. Your rows stay aligned. Pick the tool that matches the dimension count.
// io.thecodeforge // Flexbox fails: cards wrap but columns misalign .flex-cards { display: flex; flex-wrap: wrap; gap: 16px; /* second row cards shift left due to leftover space */ } // Grid fix: columns stay locked .grid-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; /* all rows align columns perfectly */ }
calc(), you're reinventing grid. Rewrite. Your future self will thank you.Grid Items Overflowing Outside Container
overflow: hidden is set.fr units automatically respect the container's size limits, but 1fr means 'take remaining space', and if content inside the item is larger than that space, it overflows.fr unit distributes free space, but items themselves can grow beyond via min-width: auto (default).min-width: 0 to the overflowing grid item. This overrides the default min-width: auto for grid items, allowing the item to shrink below its content size.- Always set
min-width: 0on grid items when usingfrunits if the item contains content with intrinsic width (images, long text, inputs). - Use
overflow: hiddenon the grid container only as a last resort — it hides the symptom, doesn't fix the cause. - Test layouts with real content, not placeholder text.
display: grid is set on the parent container. Verify grid-template-columns has multiple values, e.g. repeat(3, 1fr).gap property on the grid container. Shorthand gap sets both row-gap and column-gap. Ensure you haven't accidentally used grid-gap (old name, still works but confusing).min-width: 0 or overflow: hidden to the overflowing item. Check if the item has a fixed width, padding, or border that pushes it out.grid-template-rows: 1fr 1fr, the rows share equal height regardless of content. Switch to auto or use minmax() for flexible sizing.repeat(auto-fill, minmax(250px, 1fr)), ensure the container has a width less than the minmax threshold. Also check that auto-fill vs auto-fit is appropriate — auto-fit collapses empty tracks.grid-template-areas and grid-area. Also ensure the number of columns in each row string is identical.Check for CSS overrides: Inspect the computed styles to see if another rule overwrites `display`.Look for parent container with `display: block` that breaks grid context.display: grid !important; temporarily to verify.Under Layout tab, enable 'Show grid line numbers' and 'Show track sizes'.Also enable 'Area names' if you use named areas.In DevTools Layout panel, read the line numbers for the grid.Add temporary borders to grid items: `outline: 1px solid red`.grid-column: 1 / -1; to force full-width — if it works, the line values were wrong.Temporarily set `grid-template-columns: repeat(auto-fill, minmax(1px, 1fr))` to see if containers are being created.Use the Layout panel to see track sizes and how many columns actually exist.auto-fit instead of auto-fill.| Scenario | CSS Grid | Flexbox |
|---|---|---|
| 2D layout (rows & columns) | Perfect — designed for both axes | Workaround — nested flexes needed, fragile |
| One-dimensional row of items | Overkill — you get full 2D control but simpler tools exist | Natural fit — display: flex with gap |
| Centering a single element | Possible (place-items: center) but verbose | Trivial — align-items: center; justify-content: center |
| Card grid with unknown number of items | auto-fill handles it beautifully | Manual wrapping via flex-wrap and width calc |
| Holy grail layout (header, sidebar, main, footer) | Ideal — grid-template-areas defines structure clearly | Possible but requires nested flexes and explicit order |
| Content dictates column sizes (shrink-to-fit) | Not its strength — Grid prefers distributing space | Better — flex: 1 0 auto gives flexibility |
| Overlapping items | Native — overlapping is allowed and controllable | Not possible without absolute positioning |
| File | Command / Code | Purpose |
|---|---|---|
| simple-grid.html | Grid and Accessibility | |
| GridDebug.java | .div-container { | Grid Debugging |
| HolyGrail.java | .app-shell { | The Holy Grail Layout |
| GridVsFlex.java | .flex-cards { | Grid vs Flexbox |
Key takeaways
on items when using fr` units to prevent overflow.auto-fill preserves empty tracks; auto-fit collapses themCommon mistakes to avoid
7 patternsMemorising syntax before understanding the concept
grid-template-columns: repeat(3, 1fr) but can't explain why items overflow or how to make equal-height cards.Skipping practice and only reading theory
Not setting `min-width: 0` on grid items using `fr`
min-width: 0 to the grid item's CSS. This overrides the default min-width: auto for grid items.Using `grid-auto-flow: dense` without considering accessibility
dense for purely decorative galleries or when there's no meaningful source order (e.g., image wall). For content, use row or column.Forgetting that `gap` only works inside a grid or flex container
gap: 16px on a div that is not a grid or flex, but no spacing appears.display: grid or display: flex before using gap.Using `1fr` for all columns without considering minimum content sizes
minmax() for each column: grid-template-columns: minmax(200px, 1fr) minmax(300px, 2fr) minmax(200px, 1fr). This ensures a minimum width before fr takes over.Confusing `auto-fill` and `auto-fit`
auto-fill, you see empty column tracks that leave whitespace; with auto-fit, items unexpectedly stretch wider than expected.auto-fill. If you want items to expand to fill the available space, use auto-fit. Inspect DevTools to see the difference.Interview Questions on This Topic
Explain the difference between `justify-items`, `align-items`, `justify-content`, and `align-content` in CSS Grid.
justify-items aligns items along the inline (horizontal) axis within their cell. align-items aligns along the block (vertical) axis. justify-content aligns the entire grid along the inline axis when the grid is smaller than the container, distributing extra space between tracks. align-content does the same for the block axis. The -items properties align items inside cells, the -content properties align the tracks themselves. place-items is shorthand for both align-items and justify-items.How do you create a responsive grid that shows one column on mobile and three on desktop without media queries?
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)). The minmax sets a minimum column width (e.g., 300px). When the container is under 300px wide, only one column fits; between 300px and 600px, two columns; above 600px, three or more. auto-fill creates as many tracks as possible. Use auto-fit instead of auto-fill if you want empty tracks to collapse and items to stretch.What is the implicit grid and how do you control its sizing?
grid-auto-rows and grid-auto-columns. The default is auto, which sizes to content. You can set grid-auto-rows: minmax(100px, auto) for consistent minimum heights, or use 1fr for equal height, but then handle overflow carefully.How do you center a grid item both horizontally and vertically inside its cell, and how is that different from centering the whole grid inside the container?
justify-self: center; align-self: center on the item, or place-self: center center as shorthand. To center all items inside their cells, use place-items: center on the container. To center the entire grid (all tracks) inside the container, use justify-content: center; align-content: center on the container. The first is for items within cells, the second is for the grid structure within the container.How does `subgrid` work and when would you use it?
subgrid is a value for grid-template-rows or grid-template-columns on a grid item that is itself a grid container. It inherits the track definitions from the parent grid, allowing nested grid items to align with the parent's tracks. Example: a product card grid where the image and title need to align across rows. Use display: grid; grid-template-rows: subgrid; on the card. This is supported in Firefox and Safari, and behind a flag in Chrome as of 2026. Use it when alignment of nested items across parent tracks is critical to the design.What's the difference between `auto-fill` and `auto-fit` in `repeat()`?
minmax value and container width. auto-fill preserves empty tracks — if there is leftover space, it remains as an empty column/row. auto-fit collapses empty tracks, allowing the existing items to stretch to fill the space. In practice, auto-fill maintains the defined minimum width, while auto-fit lets items grow. Use auto-fill for a gallery where you want strict column sizes, and auto-fit for card layouts where you want items to expand.How does CSS Grid handle overflow when content is larger than the grid cell?
overflow: visible, so content that exceeds the cell will overlap adjacent items. This is the top production gotcha. To prevent overflow, set min-width: 0 on the item (overrides the default min-width: auto for grid items) and overflow: hidden or overflow: auto on the item or its content wrapper. If the item contains an image, use max-width: 100% and height: auto on the image to make it scale within the cell. Always test with realistic content lengths to catch overflow before it hits production.Frequently Asked Questions
Yes, all modern browsers support CSS Grid since 2017. For older browsers like IE11, use Autoprefixer to add vendor prefixes. The basic grid properties work, but advanced features like subgrid are not available in IE.
No. Grid is for two-dimensional layouts (rows and columns simultaneously). Flexbox is better for one-dimensional layouts (a single row or column) or when you need content-based sizing. Use Grid for page layouts and Flexbox for components like navbars or toolbars.
Use `grid-row: span N; where N is the number of rows to span. You can also use grid-row: start / end with line numbers, e.g., grid-row: 1 / 4` spans from line 1 to line 4 (3 rows).
Use gap. The grid-gap property is deprecated (though still supported). gap works for both Grid and Flexbox. Shorthand gap: 16px sets both row-gap and column-gap.
If you use repeat(3, 1fr), columns never wrap because you explicitly set 3 columns. Use repeat(auto-fill, minmax(250px, 1fr)) to make columns wrap based on container width. Ensure the container's width is less than 2 * minmax minimum to force a single column.
20+ years shipping production JavaScript and front-end systems at scale. Drawn from code that ran under real load.
That's HTML & CSS. Mark it forged?
5 min read · try the examples if you haven't