Advanced Sass : online course

Default mixin arguments for easier theming

Did you know that you can name the arguments your mixin accepts? It defines defaults and makes your arguments optional. On top of that, it gives you the ability to put your arguments in random order when including the mixin. It's great when you write mixins as part of a library that you use for managing themes or a grid system.

Most of us define mixins like below. This snippet of code is based on the Compass implementation, but simplified with the assumption that you want to set both the radius and vertical radius. It uses interpolation (#{}) to make sure that we don't end up with a division, resulting in border-radius: 2.

Play with this gist on SassMeister.

Sensible defaults

When creating a theme or library though, you want to have sensible defaults. If someone wants to set the $vertical-radius, you don't want to force them to provide $radius as well just because it's the first argument. Sass solves this by allowing you to name the arguments you send to a mixin. This means that when including the mixin, you can omit any argument except for the one you want to overwrite.

For sake of readability, I'll stick with the border-radius example. For mixins that accept more arguments than just a few, as often is the case in a library or theme, this approach becomes essential. Let's say we have a theme that uses a mixin to set both the radius and vertical radius to 10px. Others can include this mixin in their selectors without providing arguments, and they get the Company Approved Border Radius. Time to refactor the code above to use named arguments and a sensible default:

Play with this gist on SassMeister.

Our mixin now takes named arguments, both set to a default value of 10px. If you would include this mixin without any arguments, its output would be border-radius: 10px / 10px. But what if someone wants to occasionally use a different radius than the company approved one, like for the vertical radius (code above)? When including this mixin we provide a named argument to get this job done: $vertical-radius: 25px. We can omit the first argument entirely, because Sass knows that we only want to change the vertical-radius one. Now when our default radius changes, we only have to update the mixin, and not all instances where we copied 10px only because it was the only way to alter the second argument.

Optional arguments

But, did you know you can use named arguments to create optional variables that are only used when explicitly set? Here's how that could work for some mixin used in your custom Grid System Framework™.

Play with this gist on SassMeister.

This mixin sets the width of an element to 100%, whatever data you pass to it (demonstrated in the .default selector). The margin is set to 10px by default, but can be overridden. The interesting part is the default value for the $border argument though. Sass doesn't output CSS properties with a null value, so we don't need any control structures (if/else) for this argument to be optional!

Scroll down a bit in the SassMeister "Sass" panel, and you'll notice that the same can be done for the margin by overriding the default value of 10px with null (see the .without-margin selector). It completely removes the margin property from the generated CSS.

Get creative

So, get creative with named arguments and null values and write a versatile, highly (but optionally) configurable mixin for your grid system, default form styling, and so forth. Looking forward to reading in the comments how you're going to use this to improve your code!

PS: We'll dive deeper into theming and writing awesome mixins in the Advanced Sass course.

The above is part of the Advanced Sass online course, which helps you turn your Sass up to eleven. You can become a Sass expert too!