Simple Flexible Grids

Simple Flexible Grids

Grids are a major part of web design today. There are plenty of frameworks out there that bundle in robust grid systems that can do a lot but are sometimes not very flexible. Many times we just need something really simple, without all the baggage that comes with a framework.

Negative margins

This is a little trick to use some negative margins and percentage based widths (and margins) to get a nice clean grid. It’s useful for a simple image gallery or possibly some sort of grid navigation.

We’ll start with some simple HTML.

1
2
3
4
5
6
7
8
9

For the CSS, I am using SASS because I want to take advantage of mixins, variables and math to make things easy for me.

@mixin break($query) {
  @media screen and (min-width: $query) {
    @content;
  }
}

$gridMargin: 1%;

.page {
  position: relative;
  max-width: 1000px;
  margin: 0 auto;
}

header {
  background: gray;
  height: 50px;
  margin-bottom: $gridMargin;
}

.grid__wrapper {
  width: 100%;
  @include break(500px) {
    /* extra width and negative margins to make sure we are flush with the left and right sides */
    width: 100% + ($gridMargin * 2);
    margin-left: -$gridMargin;
  }
}

.grid__item {
  box-sizing: border-box;
  background: pink;
  padding: 16px;
  margin: 0 0 $gridMargin;
  @include break(500px) {
    float: left;
    margin: $gridMargin;
    width: 50% - ($gridMargin * 2); // 50% - 2% of margin
    /* clear the left column floats in case content changes height */
    &:nth-child(2n-1) {
      clear: left;
    }
  }
  @include break(800px) {
    width: 33.33% - ($gridMargin * 2); // 33.33% - 2% of margin
    /* reset nth-child from previous media query */
    &:nth-child(2n-1) {
      clear: none;
    }
    /* clear the left column floats in case content changes height */ 
    &:nth-child(3n-2) {
      clear: left;
    }
  }
}

View on codepen

FlexBox

Flexbox is pretty amazing. We can achieve the same results as above (better, really) with less code. The support for flexbox might make it a non-option for many projects but most modern browsers support it and it can be used pretty safely today. We’ll use the same HTML as above. And the SCSS below.

@mixin break($query) {
  @media screen and (min-width: $query) {
    @content;
  }
}

$gridMargin: 1%;

.page {
  position: relative;
  max-width: 1000px;
  margin: 0 auto;
}

header {
  background: gray;
  height: 50px;
  margin-bottom: $gridMargin;
}

.grid__wrapper {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}

.grid__item {
  box-sizing: border-box;
  width: 100%;
  background: pink;
  margin: 0 0 $gridMargin;
  padding: 16px;
  
  @include break(500px) {
    /* 2column - width minus half the grid margin - we're trying to get as close to 50% minus the gridMargin (in between the 2 columns) */
    width: 50% - ($gridMargin/2);
  }
  
  @include break(800px) {
    /* 3column - width minus half the grid margin - we're trying to get as close to 33.33% minus the gridMargin (in between the 3 columns) */
    width: 33.33% - ($gridMargin/1.5);
  }
  
}

View on codepen