Fixed pixel gutters on a percentage grid

trys profile image Trys Mudford ・2 min read

Although not the most riveting of subjects, grids are a fundamental building block for websites. This fixed-gutter snippet gets used on every project I build, so I thought it might be handy to share as my first Dev.to post.

In the past, I've tended to gravitate towards using percentage margins on percentage-width grids. It certainly makes the calculations easier. A two-column (50/50) grid turns into a 0/48%/4%/48%/0 grid. This system works really nicely in isolation but I've found problem starts when it slots into a design running consistent gutters.

Consider a design using 40px of vertical space between each section. If you use percentages for your horizontal margins, that neat and consistent 40px gap will shrink as the viewport closes in. Fortunately, there is a better way...

Enter the consistent margin

Sadly it's not possible to write a two-column (float-based) grid as 0/48%/40px/48%/0, mixing percentages and pixels like this will only work on some viewports. We need to use calc to bring the % and px together.

The concept is to set a pixel-based margin-left on each element (excluding the first in each row), then use calc on the element widths to account for the pixel gutter.

The width calculation is as follows:

Element width in percentage - (No of gutters * gutter width / number of elements)px

To use a real world example, for a two-column grid with a 30px gutter:

/* 50% - (1 * 30 / 2)px = 15px */
width: calc(50% - 15px);

Or a three-column grid with a 30px gutter:

/* 33.333% - (2 * 30 / 3)px = 20px */
width: calc(33.333% - 20px);

Now when a designer presents you with a five-column grid with a 35px gutter, you don't need to measure each element and translate them into percentages, just pass the values into the calculation:

/* 20% - (4 * 35 / 5)px = 28px */
width: calc(20% - 28px);

Wrapping it all up

When combined with a little nth-child goodness, you have a pretty nice bespoke grid-system:

.grid > * {
    margin-bottom: 30px;

@media screen and (min-width: 30em) {
    .grid > * {
        margin-left: 30px;
        float: left;

@media screen and (min-width: 30em) and (max-width: 45em) {
    .grid > * {
        width: calc(50% - 15px);

    .grid > :nth-child(2n+1) {
        margin-left: 0;
        clear: left;
Hey! It's 2017, we have Grid layout now, who uses float anymore?

A valid point. I still like to provide a reasonable fallback for the elderly browsers still being used in production.


Editor guide
soappmedia profile image

Awesome! i agree.. thanks for the info and for providing calculation it is more understandable thanks ..

trys profile image
Trys Mudford Author

Hey! No worries, glad it was useful :)