Abstracting grid implementation with mixins using Semantic grid - LESS CSS

Abstracting grid implementation with mixins using Semantic grid - LESS CSS

A grid system can make life a lot easier when it comes to creating the layout of page. This article demonstrates how creating a level of abstraction from our grid with mixins can make it even easier.

Demo

GitHub project

I'm a preprocessor guy

In this particular article I am using LESS as the CSS preprocessor. It's not that I have a particular bias towards LESS it's just that the project this was implemented in used LESS. The Semantic grid system runs on LESS, SCSS or Stylus.

Grids

There are plenty of grids out there to choose from. My criteria for choosing a grid was;

  • Based on LESS.
  • Usable in a responsive layout (different amount of columns at different breakpoints).
  • Easily extended and configurable.
  • Semantic (not lots of divs with col and row classes).

Based on this criteria Semantic grid system came out on top. Semantic consists of a single file to import. Within that file there are three default variables that can be overridden.

// Defaults which you can freely override
@column-width: 60;
@gutter-width: 20;
@columns: 12;

This defaults to a 12 column 960px grid system. But we can change these if we wish in our main page file.

@import 'grid.less';

// Grid will now use these values.
@column-width: 30;
@gutter-width: 20;
@columns: 6;

This is important because in a responsive layout it is common for grid size to change, so we need a way to do that at different breakpoints.

Finally there is one more variable we can override, @total-width. This defaults to a pixel value calculated from our previous variables. This means all our column and gutter sizes will be pixel values. However should we wish to create a fluid grid using percentages, we can change this variable.

@total-width: 100%;

To set a column in our CSS all we have to do is specify the column mixin from grid.less with the number of columns required.

.poster {
    // specify poster is six columns wide.
    .column(6);
}

So why bother creating mixins?

The great thing about Semantic grid is it's very unobtrusive and can be applied to any class/element you choose. So what's the point in creating another layer of obstruction to do this? One good reason to do this is responsive. As we said earlier, it is common for the grid size, column number and width to change at different breakpoints. Semantic grid can handle this but it would mean we would have to write CSS like this.

@import 'grid.less';

@column-width: 60;
@gutter-width: 20;
@columns: 12;
@total-width: 100%;

.poster {
    .column(6);

    @media screen and (max-width: 340px) {
        @column-width: 30;
        @gutter-width: 20;
        @columns: 6;

        .column(6);
    }
}

You can image how many times we would need to set the variables in a page. It would get messy and repetitive. Let's abstract the major breakpoints of the site into a mixin!

.desktop(@units) {
    @media only screen and (min-width: 601px) and (max-width: 1100px) {
        @column-width: 60;
        @gutter-width: 20;
        @columns: 12;
        @total-width: 100%;

        .column(@units);
    }
}

.mobile(@units) {
    @media only screen and (max-width: 350px) {
        @column-width: 30;
        @gutter-width: 20;
        @columns: 6;
        @total-width: 100%;

        .column(@units);
    }
}

Now our CSS looks like this.

@import 'grid.less';

.poster {
    .desktop(6);
    .mobile(6);
}

So much cleaner! These major breakpoint settings are now easily reusable across the whole project and the implementation detail is hidden away from us keeping our stylesheet clean and readable.

I have created a GitHub project with several mixin helpers and a simple working demo. Contribute, comment and use!