Left and right arrow keys navigate. Enter jumps to content.

Adding Gutters

Please enable javascript to access the full functionality of this site

Site header

npm install gutter-grid --save

Tag line

A Sass flexbox based grid system that is able to replicate CSS grid-gap in IE11

Toolbar

Preferred system:

If you have no access to CSS grid, one of the hardest things to do well in css that is also very common in web design is having multiple columns on multiple rows with gutters between each item. The content in the outer columns need to line up with the edges of the other content on the page though.

With no access to CSS grid, this is difficult to do manually but it's easy with Gutter Grid.

Defining a basic gutter size

Classes format
Using a number: grid--gutter-20
Using a name: grid--gutter-gutterName

<figure>
  <figcaption>Using a number: <code>grid--gutter-20</code></figcaption>
  <div class="grid__wrapper">
    <div class="grid grid--cols-3 grid--gutter-20">
      <div class="grid__cell -color-1"></div>
      <div class="grid__cell -color-2"></div>
      <div class="grid__cell -color-3"></div>
      <div class="grid__cell -color-4"></div>
      <div class="grid__cell -color-5"></div>
      <div class="grid__cell -color-6"></div>
    </div>
  </div>
</figure>
<figure>
  <figcaption>Using a name: <code>grid--gutter-gutterName</code></figcaption>
  <div class="grid__wrapper">
    <div class="grid grid--cols-3 grid--gutter-gutterName">
      <div class="grid__cell -color-1"></div>
      <div class="grid__cell -color-2"></div>
      <div class="grid__cell -color-3"></div>
      <div class="grid__cell -color-4"></div>
      <div class="grid__cell -color-5"></div>
      <div class="grid__cell -color-6"></div>
    </div>
  </div>
</figure>

//Define gutter sizes like this
$grid-cell-gutters: (
  20 : 20px, // Using a number
  'gutterName' : 20px,  // Using a gutter name
);

@import '../node_modules/mq-scss/mq';
@import '../node_modules/gutter-grid/grid-classes';
Mixin format

<div class="mixin__wrapper">
  <div class="mixin-12">
    <div class="mixin__cell -color-1"></div>
    <div class="mixin__cell -color-2"></div>
    <div class="mixin__cell -color-3"></div>
    <div class="mixin__cell -color-4"></div>
    <div class="mixin__cell -color-5"></div>
    <div class="mixin__cell -color-6"></div>
  </div>
</div>

.mixin__wrapper {
  // prevent margin collapse quirk
  padding-bottom: 0.1px;
}

// ---- Option 1 ----
// -- Local gutter --

.mixin-12 {
  // Short hand:
  @include grid(3, 20px);

  // Long hand:
  @include grid($cols: 3, $gutter: 20px);
}

// ---- Option 2 -----
// -- Global gutter --

//Define global gutter sizes like this
$grid-cell-gutters: (
  'gutterName' : 20px,
);

// Then import the mixin
@import '../node_modules/mq-scss/mq';
@import '../node_modules/gutter-grid/grid-mixin';

// Then state the gutter name when calling the mixin
.mixin-12 {
  @include grid(3, $gutter: 'gutterName');
}

Avoiding the collapsing margin quirk

The grid__wrapper class in the class system helps contain the grid inside it's bounding box. CSS has a bit of a quirk built into it that ignores top and bottom negative margin rules. The quirk is due to margin-collapse. The quirk is noticeable whenever the parent of the element with negative margins has its overflow set to visible and has no padding or border width.

Use padding-bottom: 0.1px on a wrapping element (or a grid__wrapper class) to prevent the bottom of the grid from blowing out as shown in this figure.

Classes format

<div class="grid grid--cols-3 grid--gutter-20">
  <div class="grid__cell -color-1"></div>
  <div class="grid__cell -color-2"></div>
  <div class="grid__cell -color-3"></div>
  <div class="grid__cell -color-4"></div>
  <div class="grid__cell -color-5"></div>
  <div class="grid__cell -color-6"></div>
</div>
Mixin format

<div class="mixin-12">
  <div class="mixin__cell -color-1"></div>
  <div class="mixin__cell -color-2"></div>
  <div class="mixin__cell -color-3"></div>
  <div class="mixin__cell -color-4"></div>
  <div class="mixin__cell -color-5"></div>
  <div class="mixin__cell -color-6"></div>
</div>

.mixin-12 {
  @include grid(3, 20px);
}

Gutter Grid tries to avoid using a top gutter + negative margin combination as much as possible. Unfortunately a bottom gutter + negative margin combo is unavoidable.

The grid__wrapper class prevents this odd behavior by using padding-bottom: 0.1px. A bottom padding of 0.1px is rounded down by browsers to a padding of 0px, however it still prevents margin collapse! What this means is that we can have the edges of our grids pressing hard up against the edges of our grid wrapper whilst still retaining a visible overflow.

If using the mixin system, padding-bottom: 0.1px needs to be added manually by you on a grid wrapper element.

Fixing the margin-collapse issue using either padding-bottom: 0.1px manually or using a grid__wrapper class.

Classes format

<div class="grid__wrapper">
  <div class="grid grid--cols-3 grid--gutter-20">
    <div class="grid__cell -color-1"></div>
    <div class="grid__cell -color-2"></div>
    <div class="grid__cell -color-3"></div>
    <div class="grid__cell -color-4"></div>
    <div class="grid__cell -color-5"></div>
    <div class="grid__cell -color-6"></div>
  </div>
</div>
Mixin format

<div class="mixin__wrapper">
  <div class="mixin-12">
    <div class="mixin__cell -color-1"></div>
    <div class="mixin__cell -color-2"></div>
    <div class="mixin__cell -color-3"></div>
    <div class="mixin__cell -color-4"></div>
    <div class="mixin__cell -color-5"></div>
    <div class="mixin__cell -color-6"></div>
  </div>
</div>

.mixin-12 {
  @include grid(3, 20px);
}
.mixin__wrapper {
  // Prevent the collapsing margin quirk
  padding-bottom: 0.1px;
}

Note: In versions prior to 7.0.0 the grid__wrapper class added overflow: hidden instead of padding-bottom: 0.1px. In v4.1.0 a grid__paddedWrapper class was added that added 1px of bottom padding for when visible overflow was needed. The grid__paddedWrapper class was removed from the class system in version 7.0.0 due to it becoming redundant.

Gutter numbers verse gutter names

Class system numbers verse names

In the class based system, you can name the gutters either with a number (grid--gutter-20) or an actual name (grid--gutter-gutterName).

By using gutter numbers, you can see directly in the HTML what the gutter value is. If this value ever needs to be globally changed though, everywhere it has been used would need to be manually updated in the HTML.

By using gutter names, if the value of the gutter ever needs to change, the value can be changed once in the style sheet and it will be updated across the whole site. Gutter names don't allow you to see the value of the gutter directly in the HTML though and, depending on how you name your gutters, it can lead to multiple gutter classes having identical gutter values (not necessarily a bad thing but it could urk some people). Coming up with meaningful names for your gutters is also more difficult than simply naming the gutters based on their values.

Gutter names are a bit more hassle to begin with but they also lead to arguably better maintainability in the long run. It is up to you and your team to decide on what the best approach for your project is.

Mixin system numbers verse names

That is only relevant if using the class system though. In the mixin based system, there are two ways you can go about applying gutters to the grid. The first option is an inline sort of format where you define the gutter size directly in the $gutter setting when calling the mixin. This makes it easy to keep all the styles for a module in the one place.

The second option is more for global gutter sizes. You define them in the $grid-cell-gutters variable in the same way as you would for the class based system. You then use the gutter name in the $gutter setting when calling the mixin. You can also use a sass variable for storing global gutter values and use that in place of a fixed pixel value.

For the sake of brevity and clarity, I'll only use the inline format for the mixin version from now on. Just know that the global format is available to you for all the gutter examples if you wish to use it.

Unequal vertical and horizontal gutters

If you have a design where the spacing between cells is different vertically to the horizontal spacing, your in luck. Gutter Grid also caters to unequal horizontal/vertical gutter sizes. This is done by providing a second pixel value. The vertical value goes first and the horizontal value goes second. This is to replicate how the short hand of setting margin and padding with 2 values goes vertical first then horizontal.

Applying a larger vertical gutter than horizontal gutter

Classes format
Using numbers
Using a name

<figure>
  <figcaption>Using numbers 
    <grid--gutter-gutter-10-30></grid--gutter-gutter-10-30>
  </figcaption>
  <div class="grid__wrapper">
    <div class="grid grid--cols-3 grid--gutter-10-30">
      <div class="grid__cell -color-1"></div>
      <div class="grid__cell -color-2"></div>
      <div class="grid__cell -color-3"></div>
      <div class="grid__cell -color-4"></div>
      <div class="grid__cell -color-5"></div>
      <div class="grid__cell -color-6"></div>
    </div>
  </div>
</figure>
<figure>
  <figcaption>Using a name 
    <grid--gutter-mixedSizeGutter></grid--gutter-mixedSizeGutter>
  </figcaption>
  <div class="grid__wrapper">
    <div class="grid grid--cols-3 grid--gutter-mixedSizeGutter">
      <div class="grid__cell -color-1"></div>
      <div class="grid__cell -color-2"></div>
      <div class="grid__cell -color-3"></div>
      <div class="grid__cell -color-4"></div>
      <div class="grid__cell -color-5"></div>
      <div class="grid__cell -color-6"></div>
    </div>
  </div>
</figure>

//Define gutter sizes like this
$grid-cell-gutters: (
  'mixedSizeGutter' : 30px 10px, // Using a name
  '10-30' : 10px 30px, // Using numbers
);

@import '../node_modules/mq-scss/mq';
@import '../node_modules/gutter-grid/grid-classes';
Mixin format

<div class="mixin__wrapper">
  <div class="mixin-46">
    <div class="mixin__cell -color-1"></div>
    <div class="mixin__cell -color-2"></div>
    <div class="mixin__cell -color-3"></div>
    <div class="mixin__cell -color-4"></div>
    <div class="mixin__cell -color-5"></div>
    <div class="mixin__cell -color-6"></div>
  </div>
</div>

.mixin__wrapper {
  padding-bottom: 0.1px;
}

.mixin-46 {
  @include grid(3, 30px 10px);
}

Media query gutters

That is how to create fixed width gutters that are the same width for all screen sizes, but what if you have a very thick gutter on desktop? It won't work well having a 50px wide gutter on a tablet or mobile device, it would take up too much screen realestate. The solution is gutters that contain media queries. Here is how to do them:

Applying gutters that are affected by media queries

Classes format

<div class="grid__wrapper">
  <div class="grid grid--cols-3 grid--noMQs grid--gutter-mediaQueryGutter">
    <div class="grid__cell -color-1"></div>
    <div class="grid__cell -color-2"></div>
    <div class="grid__cell -color-3"></div>
    <div class="grid__cell -color-4"></div>
    <div class="grid__cell -color-5"></div>
    <div class="grid__cell -color-6"></div>
  </div>
</div>

$grid-cell-gutters: (
  'basicGutter' : 20px,
  'mediaQueryGutter' : mq (
    (50px 30px), //*default gutter width of 50px vertically and 30px horizontally*/
    (30px 10px) (max, 800px), //*gutter width is 30px vertically and 10px horizontally at 800px and below*/
    10px (max, 700px) //*gutter width of 10px at 700px and below*/
  )
);

@import '../node_modules/mq-scss/mq';
@import '../node_modules/gutter-grid/grid-classes';
Mixin format

<div class="mixin__wrapper">
  <div class="mixin-13">
    <div class="mixin__cell -color-1"></div>
    <div class="mixin__cell -color-2"></div>
    <div class="mixin__cell -color-3"></div>
    <div class="mixin__cell -color-4"></div>
    <div class="mixin__cell -color-5"></div>
    <div class="mixin__cell -color-6"></div>
  </div>
</div>

.mixin-13 {
  @include grid(3, $MQs: false, $gutter: mq (
    (50px 30px), //*default gutter width of 50px vertically and 30px horizontally*/
    (30px 10px) (max, 800px), //*gutter width is 30px vertically and 10px horizontally at 800px and below*/
    10px (max, 700px) //*gutter width of 10px at 700px and below*/
  ));
}

.mixin__wrapper {
  padding-bottom: 0.1px;
}

Unlike a basic gutter which is just 1 or 2 pixel values, a media query gutter is a list of pixel values with an optional media query attached to them. When defining a gutter that contains media queries, you need to start with mq [space] then list the values. It is vitally important that you include the space after mq, otherwise it will break the system. You can also assign unequal vertical and horizontal gutters by wrapping 2 values in brackets where you would normally just place one value. The vertical value is first and the horizontal value goes second.

The media queries are written in mq-scss syntax. To learn more about how to write media queries using the mq-scss syntax, see the mq-scss documentation.

Gutters and custom breakpoints shorthand

The breakpoints setting is the 3rd Gutter Grid mixin parameter so it's possible to specify a column count, gutter size, and custom breakpoints in the mixin like so:

Column count, gutter width, breakpoints mixin shorthand. Resize the browser window to see the effect.


<div class="mixin__wrapper">
  <div class="mixin-13B">
    <div class="mixin__cell -color-1"></div>
    <div class="mixin__cell -color-2"></div>
    <div class="mixin__cell -color-3"></div>
    <div class="mixin__cell -color-4"></div>
    <div class="mixin__cell -color-5"></div>
    <div class="mixin__cell -color-6"></div>
  </div>
</div>

.mixin-13B {
  @include grid(6, 20px, (
    3 : 960px,
    2 : 600px,
    1 : 480px,
  ));
}

.mixin__wrapper {
  padding-bottom: 0.1px;
}