Better Sass through Susy with-layout mixin

I really like the Susy grid library and it does some pretty intensive things and takes strong advantage of Sass features.

Today, we’re going to look at the with-layout mixin (and the supporting _get-layout function and susy-inspect mixin) with the intent that we can learn more about Sass by looking at non-trivial real world usage.

One of the really great features of Susy is that you can completely change your grid system (different columns and gutters) just for a certain block of Sass. This works because Susy stores all of the layout settings as a Sass Map.

with-layout Mixin

[gist id=”e842edc61fa7379b672d” file=”with-layout.scss”]

Comments – Lines 1-5
Every Susy function or mixin that I’ve seen starts with a comment block that explains the purpose of the code a bit and briefly describes the parameters.

Mixin Start – Lines 6-7
It starts out pretty simple, a basic mixin with a couple parameters.

A Layout shorthand which defines the new grid system that you want to use.
Some kind of flag that we’ll figure out in the _get-layout function below.

Variable Setup – Lines 10-12
Inside the mixin, several variables are setup:

A copy of the $layout parameter that will be used for possible debugging
A local variable to save the state of the grid layout before we make this local change.
This is where the magic of with-layout really happens.

As I said before, Susy stores all of the grid settings in a single map. That map is named $susy and the with-layout mixin uses the _get-layout function (we’ll take a look at this soon) to build a new map from the $layout shorthand and then leverages the Sass !global flag to make the variable available everywhere. Without the !global flag, the variable would only be available inside the mixin.

Debugging – Line 14
Susy uses the susy-inspect mixin internally to provide debugging and variable inspection – we’ll look at that soon.

Sass Output – Line 16
The with-layout mixin is essentially a very light wrapper around some Sass that you want to use a different grid system, it leverages the @content directive to output that Sass. Now, since we have a different $susy layout map, any Susy mixins or functions used in that code will calculate columns and gutters with the grid that is specific to this block of Sass.

Restore the old Grid – Line 18
Since this grid change is only for specific code, Susy restores the original layout map so that it is available to the rest of the Sass processing. Again the !global flag is used to make the code available globally, not just within this mixin.

_get-layout Function

[gist id=”e842edc61fa7379b672d” file=”_get-layout.scss”]

Comments – Lines 1-5
Again, a simple comment block.

Function Start – Lines 6-9
A basic function with a couple parameters.

The layout shorthand that was passed in to the with-layout mixin

The same flag that was setup in the with-layout mixin parameters

Heavy Lifting – Line 10
This function doesn’t actually parse the $layout shorthand, it leverages the layout function to do that (which in turn leverages the parse-grid function to do all the actual processing).

It is important to note that Susy has both a layout mixin and a layout function. They do different things and I was at first confused about how the _get-layout function worked without creating an infinite loop because I was looking at the layout mixin (which calls the _get-layout function internally) rather than the layout function.

The Return – Line 11
Here is where the $clean flag is explained.

If $clean is false (default) then the layout map that is parsed from the $layout shorthand is merged with the $susy global layout map (which is still the original layout map because the return value of this function is set as the new global layout map). This is usually what you want to do and it lets you inherit other layout settings that you already setup like $debug or $box-sizing.

If $clean is true then the layout map that is parsed from the $layout shorthand is returned as if it was a brand new layout map without any of the existing $susy global layout map.

susy-inspect Function

[gist id=”e842edc61fa7379b672d” file=”susy-inspect.scss”]

Comments – Lines 1-5
Again, a simple comment block.

Function Start – Line 7
A basic function with a “couple” parameters.

The name of the mixin that this function was called from – passed as a string since Sass doesn’t have the ability to inspect the call stack.

The SassScript object(s) that you want to inspect.

The “second” parameter is interesting because it makes use of Sass’s variable arguments feature to allow one or more arguments to all be bundled up into a list and iterated over with @each.

Variable Setup – Line 8
We only have one variable here.

Flag to control if debug content should be output or not based on the $inspect structure

Flag Setup – Lines 10-14
This is a neat feature of Susy debugging where you can add an inspect key to a map to debug it that map without having to turn on debugging for the entire Sass file (or with-layout subsection).

It is important to note a few things:

  1. If you have multiple map arguments packaged up in a list, then adding inspect to any one of them will cause them all to be output for debugging.
  2. Since Susy uses the index Sass function, the mere presence of the inspect key will trigger output – not a “truthy” value.

Sass Output – Lines 16-18
Now, if either the $show flag is true or if you have set a inspect key on the debug map (a feature that appears to be undocumented) then Susy will output the $inspect list via the inspect Sass function.

Wrapping Up

This was only about 30 lines of actual Sass code that encompassed 3 different mixins/functions but it highlighted some interesting language features of Sass (maps and variable arguments) as well as clever design decisions in Susy (grid details in a global map that can be overridden locally) that we can learn from for our own Sass development.