One CSS Grid Line Fixed Our Entire Dashboard Layout
Our fintech dashboard had six widget cards. A balance overview, transaction history, pending settlements, currency breakdown, recent activity feed, and a notification panel. Six widgets, six media query breakpoints, and five recurring layout bugs.
Every time we added a widget or changed card dimensions, the grid broke somewhere. Cards overlapped on tablets. Orphaned widgets sat alone on ultrawide monitors. We maintained a separate flex layout for mobile that drifted out of sync with the desktop version. The CSS for this one dashboard section spanned 80 lines, most of it media queries patching edge cases.
Then I replaced all of it with one declaration.
// css.dashboard-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 1.5rem; }
No media queries. No breakpoints. No separate mobile layout. The grid handles every screen width from a phone to an ultrawide monitor.
How auto-fit + minmax works
repeat(auto-fit, minmax(320px, 1fr)) does two things at once. minmax(320px, 1fr) says each column must be at least 320 pixels wide and can grow to fill available space. auto-fit tells the browser to fit as many columns as the container width allows.
What we deleted
The old CSS had breakpoints at 480px, 768px, 1024px, 1280px, 1440px, and 1920px. Each redefined the grid column count. Adding a seventh widget meant touching every breakpoint, retesting on every device, and finding the new edge case.
The new approach eliminates the concept of breakpoints for layout. Column count becomes a function of available space, not a hardcoded integer per viewport range.
The broader lesson
Frontend layout bugs trace back to hardcoded viewport assumptions. A breakpoint at 768px assumes you know the device. A breakpoint at 1024px assumes you know the browser chrome width. auto-fit trades those assumptions for a constraint-based system: the column is at least this wide, the grid uses as many columns as fit, and the browser handles the math.
Architecture is about trade-offs, not silver bullets. For card grids, I traded 80 lines of media queries for one line of CSS Grid. Five layout bugs disappeared and never came back.
$ /related
React Server Components Made Me Rethink Client-Side
RSC doesn't just move rendering to the server. It destroys the 'client vs. server' mental model and replaces it with something sharper.
Server Components Rewired My Data Fetching
Switching from useEffect to async server components rewired my React data fetching. What changed and where client-side patterns still win.
I Replaced Three useEffect Chains With One Zustand Store and Lost 200 Lines
Three dependent useEffect chains tangled across a dashboard component. One Zustand store with derived state fixed it. Here is how the refactor went.