CSS Clamp Calculator · Guides

The Gutters Nobody Tunes

CSS clamp() for fluid grid gap: one line that keeps card spacing tight on phones and generous on desktops.

Published October 24, 2026

CSS clamp() for fluid grid gap is the spacing trick I see skipped most often. Teams fluidify their type, then their padding, then they leave the grid gap at a fixed 24 pixels and wonder why the layout feels cramped on a phone and oddly airy on a wide monitor. The gap is part of the rhythm. When everything else scales and the gutters do not, the eye catches the mismatch even if nobody can name it.

I spent a long time treating gap as a constant, partly because fixed gaps look fine in a design file. A design file shows one viewport. Real users show up at 360 pixels and at 2560 pixels, and a gap that looks generous at one width looks like a mistake at the other. On a phone, 32 pixels of gutter between two narrow cards eats a visible share of the screen. On a desktop, 16 pixels between wide cards makes the grid feel like a spreadsheet. Both problems come from the same decision to freeze the value.

The fix is one declaration, and I am going to hold it back for a paragraph because the reasoning matters more than the line. You want a minimum gap that keeps cards readable on the smallest screens, a maximum that stops the layout from drifting apart on huge screens, and a viewport factor in between that tracks how the cards themselves grow. Pick the minimum from your spacing scale, not from thin air. If your scale steps from 16 to 32 pixels, those are your guardrails.

Here it is:

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: clamp(1rem, 2.5vw, 2rem);
}

Walk the widths. At a 375 pixel phone, 2.5vw is about 9 pixels, so the 16 pixel minimum holds and the cards keep breathing room without wasting screen. At 800 pixels, 2.5vw is 20 pixels, right in the middle of the scale. At 1440 pixels it would be 36 pixels, but the 32 pixel maximum caps it, so the grid stops spreading. The gutter scales with the layout and never escapes the design system. That is the entire mechanism.

Row gaps and column gaps often want different treatment, and clamp handles that without any extra machinery. A card grid usually needs more vertical room than horizontal room, because cards stack text vertically and the eye reads down the page. Try this:

.card-grid {
  row-gap: clamp(1.5rem, 3vw, 2.5rem);
  column-gap: clamp(1rem, 2vw, 1.75rem);
}

Two things to watch. First, do not let the gap outgrow the cards. On a three column grid at desktop widths, a 48 pixel gap with 250 pixel cards looks like a parking lot. Keep the maximum gap below roughly a sixth of your typical card width and the grid stays a grid. Second, remember that gap interacts with auto-fit columns. A larger gap leaves less room for columns, so a grid that fits three cards at a fixed gap might drop to two when the gap grows. Test at the widths where columns change, and at the widths in between.

A quick aside on an older habit of mine. I used to set gaps with margins on cards and negative margins on the container, the classic workaround from before gap worked in flexbox. It produced the same visual result and twice the debugging. Gap exists now, it works in grid and flexbox in every current browser, and it never needs the negative margin trick. If you still have that pattern in a codebase, replacing it is a safe afternoon job.

Container query units are the next step if a component lands in sidebars and full width pages alike. A gap of 4cqi scales with the container instead of the viewport, so the same card grid breathes correctly in both spots. For most pages, though, viewport based clamp is enough, and it is one line you can ship today.

Frequently asked questions

How do you make grid gap fluid with clamp()?

Set gap to clamp() with a minimum, a viewport relative preferred value, and a maximum, for example gap: clamp(1rem, 2.5vw, 2rem). The gap scales with the viewport and stays inside the bounds.

Should row gap and column gap use the same clamp value?

Not always. Card grids often need a larger row gap than column gap. Set row-gap and column-gap separately so vertical breathing room can grow faster than horizontal spacing.

Why does a fluid gap change how many columns fit?

Gap consumes space inside the grid container, so a larger gap leaves less room for columns. Check the widths where auto-fit columns change, not only the smallest and largest screens.

Does clamp() work for gap in flexbox too?

Yes. The gap property works in both grid and flexbox in current browsers, and clamp() is accepted anywhere a length is accepted.

Run your own numbers before you decide.

Use the CSS Clamp Calculator to generate fluid gap values from your own spacing scale and breakpoints.

Related guides