Trys Mudford

Posted on

# Fixed pixel gutters on a percentage grid

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.