Simple grid with Sass & Flexbox

A simple and quick guide to create a grid system. I like the idea of grids-on-demand, rather than a strict framework -no matter how simple-. So I started thinking (with my buddy Nico Gonzalvez) about

Simple grid with Sass & Flexbox

A simple and quick guide to create a grid system. I like the idea of grids-on-demand, rather than a strict framework -no matter how simple-. So I started thinking (with my buddy Nico Gonzalvez) about writing some reusable code that suits almost every css styled project.


Introducing Sass

As they say:

"Sass is the most mature, stable, and powerful professional grade CSS extension language in the world."

And that's it, a simple CSS preprocessor that allows you to create shorter and less complex stylesheets. It lets you use features that don't exist in CSS yet like variables, nesting, mixins, inheritance and other goodies.

Here you can find a exhaustive guide of this preprocessor.


Creating a grid

First we need to have some HTML structure. In this example we'll make the grid using just a <ul> and some <li> tags. We also need some content, so we'll add a <span> inside the list items.

<ul class="target">  
 <li><span>1</span></li>
 <li><span>2</span></li>
 <li><span>3</span></li>
 <li><span>4</span></li>
 <li><span>5</span></li>
</ul>  

Let's add some simple styles to visualize the grid. I also added a simple reset to override the default list styles and set the main color variables.

$color0: rgb(180, 180, 180);
$color1: rgb(245, 245, 245);

* {
 box-sizing: border-box;
 font-size: 1rem;
 font-family: sans-serif;
 margin: 0;
 padding: 0;
}

ul {  
 list-style: none;

 > li {
  border: 1px solid $color0;
  text-align: center;

  span {
   background-color: $color1;
   border: 1px solid $color0;
   display: block;
   height: 100px;
   line-height: 100px;
  }
 }
}

Grid functions

We want to reuse the code, so we'll make an @extend with only the styles needed for the container. In this step we'll set the max-number of columns in a row.

$columns: 4; // Amount of columns per row

%grid {
 display: flex;
 flex-flow: row wrap;

 > * {
  min-width: 100% / $columns;
  transition: all ease-out .75s;
 }
}

The container well be a flex element so you can play around with all the flexbox properties. If you need some help here, you can check this complete guide to Flexbox.

Basically the last thing pending is to create the columns mixin. This function will allow us to set a custom column width and also some padding in case we want to separate these columns.

The code looks something like this:

@mixin col($cols, $padding-v:false, $padding-h:false) {
 $offset: 0%;

 @if $padding-v {
  padding-bottom: #{$padding-v};
  padding-top: #{$padding-v};
 }

 @if $padding-h {
  $offset: #{$padding-h * 2};

  padding-left: #{$padding-h};
  padding-right: #{$padding-h};
 }

 @if $cols {
  width: calc(#{100 / $cols}% - #{$offset});
 } @else {
  width: calc(#{100 / $columns}% - #{$offset});
 }
}

This conditionals give us the chance to maintain the "default settings" when we include the mixin without setting paddings. If you want to add only padding to a column group without changing the column width we'll just set the $cols value to "null".

After applying the styles defined, the code should look like this:

.target {
 // Extend the container styles
 @extend %grid;

 > li {
  // As an example, added padding to every column
  @include col(null, 10px, 10px);
 }

 > li:nth-child(3) {
  // The number used in the mixin divides the container width
  // In this case, the column will have a 50% width.
  @include col(2);
 }

 > li:nth-child(4) {
  // the fourth column is a 100% width box
  @include col(1);
 }
}

Here's an example of how the grid looks after we apply to the list elements we've defined above.

See the Pen SCSS Flexbox Grid by Guillermo Cura (@guillecura) on CodePen.


Browser Support

The flexbox properties are not supported by every browser, mostly you can use it from IE9 hereinafter. Here you can check the complete supported browsers list!