Web

CSS Grid: Even Columns with Space-Between Gaps Flush Edges

Learn to evenly distribute columns in CSS Grid like Flexbox space-between using gap property and minmax(0,1fr). Perfect for calculator layouts with buttons flush to container edges, no outer padding.

1 answer 1 view

How to evenly distribute columns in CSS Grid with equal gaps between them, similar to justify-content: space-between in Flexbox, ensuring buttons align flush to container edges?

I’m building a calculator layout using CSS Grid for buttons arranged in 4 columns. I want even spacing between columns (like Flexbox space-between), with the leftmost and rightmost buttons flush against the container’s left and right edges—no extra space on the sides.

Current HTML Structure

html
<div class="calculator">
 <div class="screen">Screen</div>
 <div class="button-container">
 <button>AC</button>
 <button>()</button>
 <button>%</button>
 <button>+</button>
 <button>7</button>
 <button>8</button>
 <button>9</button>
 <button>*</button>
 <button>4</button>
 <button>5</button>
 <button>6</button>
 <button>-</button>
 </div>
</div>

Current CSS

css
.calculator {
 border-radius: 1.5rem;
 min-height: 80vh;
 max-width: 350px;
 background-color: #fae4e4;
 padding: 1rem;
 margin: 0 auto;
 box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.screen {
 min-height: 100px;
 border-radius: 1rem 1rem 0 0;
 background-color: #ded3d3;
 padding: 1rem;
 display: flex;
 align-items: center;
 justify-content: flex-end;
 font-size: 2rem;
}

.button-container {
 padding-top: 0.5rem;
 display: grid;
 grid-template-columns: repeat(4, 1fr);
 justify-content: space-between;
 row-gap: 1rem;
 text-align: center;
}

.button-container button {
 border-radius: 50%;
 height: 3rem;
 width: 3rem;
 background-color: #ffcccc;
 border: none;
 font-size: 1.5rem;
 cursor: pointer;
 transition: background-color 0.3s;
}

.button-container button:hover {
 background-color: #ffb3b3;
}

Problem

Using grid-template-columns: repeat(4, 1fr) creates equal-width columns, but justify-content: space-between doesn’t distribute space evenly between columns as in Flexbox. I need consistent gaps between columns and no padding/margin on the outer edges.

What I’ve Tried

  • justify-content: space-between on .button-container: No effect on grid column spacing.
  • Adjusting gap: Adds space between but doesn’t ensure flush edges or even distribution like space-between.

Desired Outcome

  • Equal gaps only between the 4 columns.
  • First column button touches left edge of .button-container.
  • Last column button touches right edge.
  • Works responsively within the calculator container.

Use CSS Grid’s gap (column-gap) and proper track sizing — not justify-content — to get equal space between columns while keeping the outer columns flush. Change your grid to grid-template-columns: repeat(4, minmax(0, 1fr)), use gap (or column-gap) for the spacing, remove any horizontal padding on the grid container, and either make buttons fill their column or snap the first/last column items to start/end with justify-self (nth-child).


Contents


How CSS Grid handles spacing — gap vs justify-content

Why doesn’t justify-content: space-between do what it does in Flexbox? In Grid, justify-content aligns the entire grid block inside the container; it doesn’t distribute space between columns. The property that creates equal space between grid tracks is gap (or its longhands column-gap / row-gap) — it adds space only between items, not at the outer edges, which is exactly what you want. See the MDN note on the relationship of Grid layout and the gap behaviour for confirmation: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout/Relationship_of_grid_layout and the column-gap reference: https://developer.mozilla.org/en-US/docs/Web/CSS/column-gap.

In short: use gap for equal inter-column spacing and make sure your grid tracks are sized so the grid spans the container (so the first/last tracks sit flush).

I’ll show two practical ways to achieve your calculator layout below.


Minimal CSS fix — gap & grid-template-columns (copy/paste)

Replace the .button-container block and add two small rules. This keeps your circular buttons (3rem) and makes the leftmost/rightmost buttons touch the grid edges while keeping equal gaps between columns.

css
.button-container {
 /* keep the top spacing, but remove horizontal padding so grid edges = container edges */
 padding-top: 0.5rem;
 padding-left: 0;
 padding-right: 0;

 display: grid;
 /* allow tracks to shrink below min-content and share remaining space equally */
 grid-template-columns: repeat(4, minmax(0, 1fr));

 /* equal spacing only between columns/rows */
 gap: 1rem; /* shorthand sets both column-gap and row-gap */
 row-gap: 1rem;

 /* center items by default (so middle column buttons look centered) */
 justify-items: center;
 align-items: center;
}

/* snap items that live in column 1 to the left edge of their track,
 and items in column 4 to the right edge of their track */
.button-container > *:nth-child(4n+1) { justify-self: start; } /* col 1, 5, 9... */
.button-container > *:nth-child(4n) { justify-self: end; } /* col 4, 8, 12... */

/* keep your button look */
.button-container button {
 width: 3rem;
 height: 3rem;
 border-radius: 50%;
 background-color: #ffcccc;
 border: none;
 font-size: 1.5rem;
 cursor: pointer;
 transition: background-color 0.3s;
}

Why this works:

  • gap only creates room between columns — the first and last grid tracks remain flush to the container edges.
  • minmax(0, 1fr) prevents the columns from being widened by intrinsic content, so the grid actually divides the available width evenly.
  • The nth-child rules place first/last column buttons at the track edges while leaving other buttons centered.

If you want every button to reach the edges of its track (no centering hacks), see Option A below.


Two practical approaches: fill columns vs fixed circular buttons

Option A — Buttons fill each column (simplest flush edges)

Make each button fill its column. This guarantees the button (or its visible box) touches the container edges without special selectors.

css
.button-container {
 grid-template-columns: repeat(4, minmax(0, 1fr));
 gap: 1rem;
 justify-items: stretch;
 align-items: stretch;
 padding-left: 0;
 padding-right: 0;
}

.button-container button {
 width: 100%;
 aspect-ratio: 1 / 1; /* keep square buttons */
 max-width: 4rem; /* optional cap on very wide screens */
 border-radius: 0.5rem; /* or 50% if you prefer circles */
}

Pros:

  • Zero hacks; first and last columns are flush automatically.
  • Responsive: columns scale, buttons keep square shape via aspect-ratio.

Cons:

  • Buttons size = available column width; you may need max-width so they don’t become huge on wide screens.

Relevant reference on gap: https://developer.mozilla.org/en-US/docs/Web/CSS/column-gap and the CSS-Tricks Grid guide: https://css-tricks.com/snippets/css/complete-guide-grid/

Option B — Fixed-size circular buttons, edges flush using nth-child (keeps 3rem circles)

This is the copy/paste solution in the Minimal CSS fix. It preserves 3rem circular buttons, centers interior column buttons, and forces the outer column items to hug the edges:

  • Use grid-template-columns: repeat(4, minmax(0, 1fr))
  • Use gap: 1rem
  • Set justify-items: center
  • Then target items in the first and fourth column with nth-child selectors to start / end

This keeps the aesthetic of small circular buttons while meeting your flush-edge requirement.

Reference example and community discussion of similar tactics: https://stackoverflow.com/questions/46951008/equal-space-between-grid-items-with-first-and-last-pinned-to-container-edges and https://stackoverflow.com/questions/70770416/how-do-make-columns-in-a-grid-space-evenly-like-with-flexbox


Responsive tweaks and accessibility

  • Prevent overly-small columns by using a minimum: grid-template-columns: repeat(4, minmax(44px, 1fr)); — that ensures each button has a usable minimum on small screens.
  • Or use repeat(auto-fit, minmax(44px, 1fr)) if you want fewer columns on tiny screens.
  • Keep box-sizing: border-box; globally to avoid unexpected width calculations.
  • For keyboard users, add a visible focus style:
css
.button-container button:focus {
outline: 2px solid #333;
outline-offset: 2px;
}
  • If you need the buttons to be visually flush with the outer edge of the whole .calculator (not just .button-container), remove horizontal padding from .calculator or move padding to .screen so the grid can span full width. Avoid negative margins — restructure instead.

For a calculator UI tutorial that uses grid and gap for neat layouts, see https://freshman.tech/css-grid-calculator/ and general grid examples at https://gridbyexample.com/examples/example33/.


Debug checklist

If things still look off, check this:

  • Remove any horizontal padding on .button-container (and/or verify .calculator doesn’t add unwanted padding).
  • Confirm gap is set (open Styles in DevTools and look at column-gap / row-gap).
  • Verify grid-template-columns uses minmax(0, 1fr) rather than plain 1fr if content is wide.
  • Check for margins on the button elements — margins create extra outer spacing.
  • Use browser DevTools’ Grid inspector to see tracks/gaps (Chrome/Firefox have grid overlays).
  • If you used nth-child selectors, make sure your element count and column count match (nth-child(4n+1) and nth-child(4n) for 4 columns).

Sources


Conclusion

CSS Grid gives you the exact behavior you want when you use the gap property and proper track sizing (minmax(0, 1fr)). Remove horizontal padding on the grid container, use gap for equal inter-column spacing, and choose one of two patterns: make buttons fill each column (simpler) or keep fixed-size buttons and snap first/last column items to edges with justify-self (nth-child). Try the minimal copy/paste fix above — it should give you evenly distributed columns, equal gaps, and outer buttons flush to the .button-container edges.

Authors
Verified by moderation
Moderation
CSS Grid: Even Columns with Space-Between Gaps Flush Edges