ToolNest logoToolNest.

Common CSS Grid Mistakes (and How to Fix Them)

The most common CSS Grid mistakes are doubling gaps with margins, sizing tracks with percentages instead of fr, and confusing justify- with align- properties. Each one is fixable in a single line — identify yours with our free CSS grid generator and the ten fixes below.

Gap vs margin: the doubled-spacing bug

The classic Grid beginner bug: adding gap: 24px to the container and margin: 24px to the cards inside it. The result is 48 pixels between items instead of 24, and an outer edge that no longer aligns with the rest of the page. Gutters in Grid belong to the container via gap, not to the items via margin — gap is spacing between tracks, and it deliberately does not add space at the container's outer edges. This matters the moment your grid must align with other page elements: a card gallery with gap: 24px keeps its outer cards flush with the headline above, while the margin version pushes everything 24 pixels inward and looks broken. The fix is one line: delete the item margins and keep the gap. The reverse mistake also exists — developers who learned Grid before gap was universal still wrap items in padding-and-margin math, recreating the old Bootstrap gutter hack inside a system that solved it. If you need spacing inside a card (between its image and text), that is the card's padding — container-level concern vs item-level concern. Rule of thumb: gap for between-items, padding for inside-items, margin for outside the container. Check any inherited component styles too: a card component that worked in a Flexbox context may carry margins that double up the moment you drop it into a Grid.

Sizing tracks with % instead of fr

Writing grid-template-columns: 33.33% 33.33% 33.33%; looks right until you add gap: 24px — then the three columns plus two 24-pixel gaps total 100% + 48px, and the third column wraps to a new row. The fr unit exists precisely to avoid this: repeat(3, 1fr) divides the available space after gaps are subtracted, so it never overflows. On a 960-pixel container with a 24-pixel gap, each column becomes exactly (960 − 48) ÷ 3 = 304 pixels — computed by the browser, immune to rounding. The percentage version also breaks when you add borders or padding to the container, since percentages resolve against the full width. The deeper trap is mixing fixed and percentage tracks: 280px 1fr gives the sidebar exactly 280 pixels and content the rest, while 280px 70% overflows the container by definition. And watch out for fr with min-content minimums: 1fr actually means minmax(auto, 1fr), so an item with a 400-pixel image inside a 304-pixel column will blow the track out to 400 pixels unless you write minmax(0, 1fr). That single fix — minmax(0, 1fr) — resolves more 'my grid overflows on mobile' reports than any other change. If you are prototyping track sizes, a visual grid builder shows the computed widths live so the fr math is never a mystery.

Justify vs align: the axis mix-up

Grid has two axes and two property families, and mixing them up is the most common source of 'why won't this center.' justify-* controls the inline (horizontal) axis; align-* controls the block (vertical) axis. justify-items aligns items inside their cells horizontally; justify-content aligns the whole grid inside the container when there is leftover space. So align-items: center centers each card's content vertically within its cell, while align-content: center centers the entire grid block vertically in the container. The debugging trick: ask whether you are positioning things in cells (use -items) or cells in the container (use -content). A frequent sight: justify-content: center on a full-width grid doing absolutely nothing, because the grid already fills the container — the developer wanted justify-items: center on the cards' inner content. The shorthand place-items: center sets both axes at once and is the fastest way to center content in a cell. One more gotcha: stretch is the default for both, so items fill their cells unless told otherwise — if your cards look weirdly tall, that is align-items: stretch doing its job, not a bug. Overriding with align-items: start returns cards to their natural height.

Implicit grid blowouts and missing minmax()

Mistake seven: relying on the implicit grid without sizing it. When you place more items than your explicit tracks hold, Grid creates implicit rows sized auto — content height — which is why a gallery with 13 cards in a 3×4 grid gets a ragged 13th row of unpredictable height. Set grid-auto-rows explicitly (e.g. grid-auto-rows: minmax(180px, auto)) so overflow rows behave. Mistake eight: responsive tracks without minmax(). repeat(auto-fill, minmax(240px, 1fr)) is the famous responsive-gallery pattern; drop the minmax() and use fixed 240px tracks, and columns overflow small screens instead of reflowing. Mistake nine: forgetting subgrid's absence — nested grids do not inherit the parent's tracks, so a card with its own internal grid will not align with sibling cards' internals; subgrid fixes this but still needs a fallback in older browsers. Mistake ten: using line numbers instead of names in complex layouts — grid-column: 2 / 5 is fragile when a sidebar is added later; named lines or areas survive redesigns. The meta-lesson: Grid fails silently more than it fails loudly. When a layout looks wrong, inspect the grid overlay in DevTools — track lines, area names, and implicit tracks are all visible there, and most of these ten mistakes announce themselves in the overlay before they make sense in the code. For the markup layer that wraps any finished layout, see our meta description guide. When the layout is done, validate the surrounding workflow: convert project docs with the markdown to HTML converter, sanity-check copy with the word counter, and review our three-color gradient guide for the next visual layer.

Do it in one click

Preview your grid and catch layout bugs visually — free tool.

Open the Free Tool →