CSS Grid’s repeat() function is one of the most reliable tools in a modern stylesheet — until the number of items you’re rendering doesn’t divide evenly into the number of columns you asked for. Then the last row doesn’t fill, and a component that looked perfect in a 6-item mockup looks obviously unfinished with 5.
We found this exact bug five times while rebuilding kodenzo.com. Not five variations of it — the literal same root cause, in five different components, because each one was built by choosing a fixed column count first and checking the real item count second.
Where it showed up
A product ecosystem grid with five real product cards, dropped into a fixed 3-column layout, left one card stranded alone on the second row. A “Who We Build For” section had the same problem at a different item count. A Technical Highlights section on a case study page sliced its feature list down to fit a 4-column grid, when every case study only had three real features to show. A technology grid on the About page had fifteen items against a column count that didn’t divide evenly. Most recently, an Insights grid with exactly three cards would have broken at its own tablet breakpoint — not because the desktop layout was wrong, but because the responsive step between desktop and mobile introduced a two-column tier that a three-item grid can’t fill cleanly.
That last one is worth sitting with, because it’s the version of this bug that’s easiest to miss in review. The desktop layout looks right. The mobile layout looks right. The bug only exists in the breakpoint inherited from a different component, applied without checking whether it made sense for this one.
Two real fixes, chosen deliberately
The first fix is architectural: switch-wrap instead of a fixed column count. display: flex; flex-wrap: wrap; justify-content: center;with flex: 1 1 {basis}px on each child lets the browser figure out how many columns actually fit, rather than committing to a number up front. This is the right fix when the item count is expected to change over time — a product ecosystem that will keep growing shouldn’t have its grid hand-tuned every time a card is added.
The second fix is simpler and often better: pick a column count that’s an exact multiple of your real item count, on purpose. Eight cards fit a 4-column grid in two clean rows. Six cards fit a 3-column grid in two clean rows. Twelve category tiles fit a 4-column grid in three clean rows. When the content is fixed and known — which is more often true than it first appears — choosing the grid to match the content beats making the grid flexible enough to handle content it will never actually receive.
The rule that actually stuck
The lesson wasn’t “use flexbox” or “use grid” — it was to stop treating column count as a design decision made independently of the real item count. Every fixed grid on this site now gets one question asked of it before it ships: does this column count divide evenly into how many items will actually be here, at every breakpoint, not just the widest one. It’s a small check. It caught a real bug the very next time we ran it, before that one ever reached production.