DEV Community

Trys Mudford
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
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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

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

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);
Enter fullscreen mode Exit fullscreen mode

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;
    }
}
Enter fullscreen mode Exit fullscreen mode
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.

Oldest comments (2)

Collapse
 
soappmedia profile image
SoAppMedia

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

Collapse
 
trys profile image
Trys Mudford

Hey! No worries, glad it was useful :)