Sleeping Columns Using the Semantic Grid System

So a couple of weeks ago I was working on building a complex responsive grid that had different column widths at different breakpoints, and blogged about it here. I found this system works pretty well and is very scalable, meaning I can quickly build complex responsive templates for new layouts on a site. However, all those classes are pretty cumbersome to work with and also mean that you’re putting all that presentational stuff into your markup. Then I came across Tyler Tate’s Semantic Grid System and I thought it might be useful to try this as an alternative.

The nice thing about Tyler’s solution is that it hides all the complexity off somewhere else (i.e. in the file grid.less that you need to include) and lets you specify your grid in a fairly simple way. Even better, there’s no need to add all those unsemantic classes into your markup. The extra constraint is that you have to use a CSS pre-processor such as LESS, so if you’re not already doing that, it does mean making some changes to your workflow. But after a bit of fiddling around I managed to get my example layout working with the Semantic Grid method instead.

@total-width: 100%;
@columns: 12;
@column-width: 5.625;
@gutter-width: 2.5;

#wrapper { padding: 1.25%; }
        
@media (min-width: 768px) and (max-width: 959px) {
        
    #header { .column(12); }
    .main-wrap { .column(8) }
    .side1 { .row(8); } /* Nested column container needs to be a row */
    .side1a, .side1b { .column(4,8) } /* Nested columns */
    .side2 { .column(4) }

}

@media (min-width: 960px) {
        
    #header { .column(12); }
    .main { .column(6) }
    .side1 { .column(3) }
    .side2 { .column(3) }
        
}       

As with my original approach, there is quite a bit of complexity in getting the nested columns to work, and this probably is the most fiddly part of the Semantic Grid code. Basically you need to pass a second parameter to the column mixin to your nested columns, as well as applying a .row mixin to the parent column. But having figured this out, it’s not too hard to use. Another small issue was that Tyler’s grid uses a system of equal numbers of columns and gutters, which means that you get right and left page margins equal to half a gutter width. I wanted a full gutter width either side, which looks a bit more balanced to me. Luckily I found it was possible to achieve a close approximation of this by adding an extra wrapper DIV around everything and applying a bit of padding to it.

CSS Sleeping Columns in Responsive Layouts

Fluid CSS grids are great because they give us a way to align content into a grid that responds to the width of the browser or device screen. However, as the underlying grid gets narrower we usually want to rearrange the columns so as to retain a comfortable amount of space for the content. Sometimes, of course, this means splitting a column into two new columns as it drops down into a new position.

Fluid CSS grids like this and this don’t seem to cover these kinds of complex break points. If your site has only a few templates then it’s not too hard to give each column a class and then assign them different widths as your media queries fire. But while I was working on some responsive templates for a really big website recently I started wondering about how to code these columns in a more systematic, re-usable way.

@media (min-width: 768px) and (max-width: 959px) {
    /* Tablet layout columns wake up here: */

    .tcl3, .tcl4, .tcl6, .tcl8, .tcl12 {
        float: left;
        margin-left: 2%;
    }

    .tcl3 { width: 22.5%; }
    .tcl4 { width: 30.666666666667%; }
    .tcl6 { width: 47%; }
    .tcl8 { width: 63.333333333333%; }
    .tcl12 { width: 96%; }
    .tcl-last { margin-right: 2%; }
}

@media (min-width: 960px) {
    /* Desktop layout columns wake up here: */

    .dcl3, .dcl4, .dcl6, .dcl8, .dcl9, .dcl12 {
        float: left;
        margin-left: 2.5%;
    }

    .dcl3 { width: 21.875%; }
    .dcl4 { width: 30%; }
    .dcl6 { width: 46.25%; }
    .dcl8 { width: 62.5%; }
    .dcl9 { width: 70.625%; }
    .dcl12 { width: 95%; }
    .dcl-last { margin-right: 2.5%; }

}

So what we have here is a system of classes for both ‘tablet view columns’ (.tcl) and ‘desktop view columns’ (.dcl), both working off the same underlying 12 column grid. Sometimes a tablet column and desktop column can share the same DIV. So for example <div class="tcl4 dcl3"> takes up 4 grid columns on a tablet, but only 3 grid columns on a desktop screen. But in other cases the columns will require separate DIVs, for instance if a single long desktop column needs to split into two separate tablet columns because it is slipping into a wider area.

Granted this is all quite complicated and can make your head hurt at times, especially when trying to put the markup together for a complex page. But the advantage of this approach is that after it is set up, we end up with a system of classes that can be applied to different layout templates fairly quickly, and without having to worry about percentages. Source order is still a limitation of course, and prevents us from using some layout combinations. To get round that you probably have to use Javascript to manipulate the DOM.