Creating a responsive layout in SASS with the Semantic Grid system

Little boxes - East 30th Street
Little boxes on East 30th Street by A Great Big City on Flickr

I recently added a new mobile layout to gun8 using the Semantic Grid system! I was thankful to find a solution in SASS, and it was simple to integrate into the layout I had already written.

Many grid systems work by littering your HTML with specific class names to control the size and position of elements, but Semantic Grid works as a SASS (or Less, or Stylus) plug-in that programmatically adds widths and margins to the containers you specify.

The setup is as simple as declaring variables that control the grid, then @include the function in your existing style declarations. Here’s a very basic example that shows how I incorporated it into the gun8 layout:

At the top of main.sass, I @import the grid.scss file. There are default variables included in the grid.scss file which specify a 12-column grid with 60px columns and 30px gutters, but these can be overridden in your SASS stylesheet by setting the $columns, $column-width, and $gutter-width variables.

Next comes the real magic! You can switch to a fluid-width layout by just changing the $total-width variable to “100%”. This automatically changes column and gutter sizes to be percentages instead of pixel-widths!

To add the fluid grid, all I had to do was add @include statements on my pre-existing content and sidebar containers. The widths are still given in “numbers of columns” even though we’re using a percentage-based layout, so I kept the layout at 12 columns and used @include column(9) on the content container and @include column(3) on the sidebar.

How does that become responsive? Well, the percentages keep things in the proper proportions, but, for smaller screens, I added a media query that takes effect when the screen width is under 960px. Here’s the simple media query that makes the containers full width:

@media only screen and (max-width: 960px)
  #content
    @include column(12)
  #sidebar
    @include column(12)

Since the layout is 12 columns wide, the layout is 100% width, and the containers are floated left, that makes the sidebar snap down below the content and fill up the full width on devices with smaller screens. Try it out by visiting gun8.com on your phone/tablet or resize your browser window to be smaller than 960px.

Problems:

With gun8’s layout, I have everything in one wrapper (with the orange border) that contains the content and sidebar. It’s also padded so that whatever is inside is spaced away from the border by 30px. This became a problem with the containers inside, since there is currently no way in Semantic Grid to leave off gutters – each element will have half of $gutter-width appended on the right and left side, which was making the main wrapper’s padding inconsistent. Since I was using 30px to pad the wrapper and the gutter width is a percentage, I changed the padding of the main wrapper to be 30px top and bottom and (30px - $gutter-width*0.5) on the sides, to compensate for the half-gutter-width that would be added!

The process of integrating the layout was simple, but dealing with iframes, embeds, and images in blogs posts has been an issue. Youtube videos and embedded Twitter posts have dimensions pre-defined in HTML, so that when the responsive layout resizes, those fixed-width elements break outside their container and cause layout issues. Using javascript to remove the width and height is pretty simple, but I haven’t settled on what I’ll do yet. My current solution is kind of hacky until I think about it a bit more – I’ve added rules that modify iframes and embeds to be 100% width and 300px height, and images are set to max-width: 100% and height: auto so they will scale at small resolutions.

For a better solution, you’d need something like FitVids.js or the video container div solution like Boing Boing uses.

So that’s that! For more info, visit semantic.gs or if you have a question, you can leave a comment below.