8 Sass mixins you must have in your toolbox

Published January 15, 2014

At their core, Sass mixins are blocks of code that you define once and can then re-use anywhere, if you are familiar with any programming language you can think of them as functions. A mixin can take multiple parameters and make calls to functions to in the end output CSS, and they are super useful when you want really clean and DRY code.
Some of the mixins below are already included in the Compass library, but since I prefer not to use Compass in my projects, I decided to write them myself.

So, here are the 8 mixins I think every developer should have in their toolbox.

1. Set a rem font size with pixel fallback

Rem is similar to the em value, but instead of being relative to the parent element it’srelative to the font-size set in the <html>.
It has all the benefits of em but you don’t get issues with e.g (compounding) since rem is only relative to the html element. The bad part is there’s no support for rem units in IE8 and below. But with this mixin we can create a fallback to pixels when rem isn’t supported.

Usage

Output

2. Breakpoints

When Sass 3.2 was released some time ago, they made it possible to define names to our media queries, which makes the usage of them a lot cleaner. Instead of calling them @media (min-width: 600px) we can give them more semantic names like “breakpoint-large” or “breakpoint-a-really-large-computer-machine”.

Output

3. SVG background images with PNG and retina fallback

This mixin depends on Modernizr and creates a bit more work for you when creating images for your site, but it’s really worth it in the end.
You need one .svg file, that will serve as the default background image. You’ll also need a regular .png that serves as a fallback for non-svg-supporting browsers. And last you need a twice as large .png as a second fallback to retina screens.
All in all you need this:

Usage

.container-with-floated-children {
@extend %clearfix;
}

8. Visually hide an element

When you hide an element with display: none, that prevents screen readers from reading it to the user. Sometimes that’s fine, but in other cases this will make the site hard to use for people with screen readers. Thus, we have to use another technique for hiding elements while at the same time make them accessible.
In this example, we are using the Sass placeholder selector since the output will always be the same, which enables us to reduce repetetive code in the output.

Nice work, Sebastian, and very useful. A few small corrections: you don’t need to generate -ms- prefixed code for transitions, animations and keyframes. IE has never used them: the browser’s support went straight to the CSS final version.

I agree. I wish more people knew about Autoprefixer – it does what they setup mixins to do, only better, because you don’t end up with unnecessary css declarations in the end and it can even clean up extra rules you don’t need like -ms- as mentioned in the previous comment.

With some modifications to certain mixins, that have already been mentioned in the comments, I’d say this is a pretty solid list.

The only thing I’d strike from here is the Opacity mixin. I personally just hate adding/promoting the use of IE filters in stylesheets.

Instead I’d add in a mixin for gradients, as those are still quite an annoyance to write out with all the vendor prefixes (and depending on how far back your browser support goes, the early drafts of the vendor prefixes that need to be in there)

Also, one little nitpick. This article is really about 7 mixins and a silent class (looking at you %clearfix)

An issue I can see with this technique is that you might end up with a lot of different breakpoint sizes. Which can make the code difficult to maintain and hard to remember what pixel breakpoints that you’ve set earlier.

I prefer to set a maximum of 3-4 different ones with more rememberable names for this reason. And I would also recommend setting the breakpoints in em’s instead of pixels to enable zoom support. You can read more about that here.

I don’t think it’s hard to maintain as long as you keep all queries associated with the element at one place/partial.

There are off course pros and cons but I often find that when I’m developing with specific breakpoint sizes, I also get specific layouts. I usually implement a certain behavior and then scale it to the point where the behavior isn’t doing the trick anymore. I think that that should be the breakpoint, rather than a absolute value. Maybe a combination of the two is a good solution

Be careful with #4 and #5, they are useless if you try to pass a vendor prefixed property. For instance, something like this:
@include keyframes(slide-down) {
0% { -wtf-transform: translateY(100%); }
90% { -wtf-transform: translateY(0%); }
}
or
@include transition(-wtf-transform .3s ease);
This wouldn’t work cross browser because the only way to pass vendor prefixed properties into the mixin’s @content variable would be to write a complexe @if @else logic to resolve which vendor should be applied to which property. Which is possible, Compass and Bourbon both have complicated *prefixer* mixins to deal with this.

Personally, I switched to Autoprefixer (which is a postprocessor, I use it with Grunt). It handles this *issue* like a charm. Now, I can write my animations and transitions the *standard css way*, without even thinking about vendor prefixes, I don’t even need @mixins for animation, transition, and keyframes.

So when I write this in my .scss files:
transition: transform .3s ease;
it is autoprefixed like this in the final .css file:
-webkit-transition: -webkit-transform .3s ease;
-moz-transition: -moz-transform .3s ease;
-ms-transition: -ms-transform .3s ease;
transition: transform .3s ease;

You can even customize how many browsers versions you want to support (it uses Caniuse.com API to resolve vendor prefixes).

I use px-rem conversions for any measure I want to have the fluidity and ease of rem with IE fallback: element width, height, margin, padding, etc. (I know I could do those in ems based on element font-size, but this keeps math easier. To handle multiple values for padding/margin, I’ve cobbled together the following mixin & function:

Great article! love the svg with fallback mixin. I have a mixin in my utility belt for resizing sprites that could be really helpful to compliment that. http://hackingui.com/front-end/10-best-scss-utilities/
When I get the chance will probably do some refactoring to incorporate SVG as well

Re 4 Animations and keyframes and 5 Transitions: The idea behind vendor prefixes was not to include every imaginable prefix.

There has never been a -ms- prefix for neither the keyframes at-rule nor the animation and transition properties (except for pre-release IE10 beta versions, maybe). IE ≤ 9 do not support animations and transitions; IE ≥ 10 support them prefix-free.

Firefox has also supported animations and transitions prefix-free for quite some time now, no need for -moz- anymore. The latest Presto Opera has also dropped the -o- prefix. So the only remaining prefix is -webkit-.

The keyframes, animation and transition mixins should not generate useless declarations, but only use the -webkit- prefix and the prefix-free variants (in that order).

I agree that you should only use the necessary vendor prefixes. But I also think that using all prefixes, even the uncessecary ones, do more good than harm.
Tools such as Compass and Grunts autoprefixer plugin are great in this regard, where the necessary vendor prefixes are always up to date and used.

But I think in general, using all vendor prefixes instead of the required ones, though bloating your CSS with unecessary lines of code, still is better than manually having to go through your mixins to make sure they are up to date every other week. And you still catch some old/beta version of e.g Firefox that still uses the prefixed property.

But as I said, this article focues on Sass without the help of Compass or Grunt. If you already use those tools in your project the mixins you mentioned shouldn’t be used at all since they take care of them automatically.

Hi Sebastian,
Came across a tweet from Changelog about this post. Nice work! It’s amazing how little things like these snips help to speed up our work flow. It’s also cool to see I’m not the only one who uses the “bp-size” name for breakpoints.

For anyone who is interested I created a GitHub Gist with all of these snips as separate Sass files along with a simple set of usage instructions:

What exactly is the point of creating a placeholder in number 8 when you just create a class called “.visually-hidden” and extend the placeholder there.

Wouldn’t it be more effective, and semantic to just make the class “.visually-hidden” and apply that to any of the html that you want to hide, visually, rather than add the extra complexity of creating the placeholder just to extend that in the class?

This is awesome information, especially the rem font size with pixel fallback mixin.

I personally don’t worry about vendor prefixes anymore since I started using Autoprefixer (https://github.com/postcss/autoprefixer). All I do is write the CSS property or value in their normal form and Autoprefixer takes care of the rest after compilation (SCSS).

Regarding named media queries, they work well for device-specific breakpoints since you’d only be creating a handful of them, hence, relatively easy to remember.

But if you’re creating content-based breakpoints, then you’re very likely to create much more than a handful of breakpoints and remembering which breakpoint “breakpoint-a-really-large-computer-machine” is, becomes more a hassle than help.