There are  a whole host of Sass mixin libraries out there: Bourbon is a personal favourite, Compass is hugely popular. But sometimes, actually always, it’s better to pick and mix your mixins to suit yourself.

It’s never good to rely too heavily on a tool, and if you think Sass mixins begin and end with the @include statement then you should probably try writing out a few of your own.

Sass mixins are available for a huge range of tasks, here’s 15 that no developer should be without:

box-sizing

Sass, like all preprocessors is great for taking out the vendor prefixes from your code. This mixin sets box-sizing and handle the prefixes once:

@mixin box-sizing($type)
 {
 -webkit-box-sizing:$type;
 -moz-box-sizing:$type;
 box-sizing:$type;
 }

Usage:

div {
 @include box-sizing(border-box);
 }

opacity

Frequently, you want to set not only vendor prefixes but use different syntax altogether. This mixin sets opacity for current browsers and older IE:

@mixin opacity($opacity) {
     opacity: $opacity;
    filter: alpha(opacity=($opacity * 100));
 }

Usage:

div {
 @include opacity(0.5);
 }

column-width

column-width is one of the best examples of a mixin taking care of browser prefixes:

@mixin column-width ( $value: 150px ) {
     -webkit-column-width: $value;
    -moz-column-width: $value;
    column-width: $value;
 }

Usage:

div {
 @include column-width(150px);
 }

circle

Once you’ve set up a mixin like border-radius, you can use it in other mixins, in this case to make a rectangular div circular:

@mixin circle
 {
 @include border-radius(100%);
 }

Usage:

div {
 @include circle();
 }

font-size

Mixins are great for progressive enhancement. This mixin sets the font-size in pixels, then overwrites that by setting it in rems. rems will only be used if the browser in question supports them:

@mixin font-size($size) {
     font-size:$size;
 font-size: ($size / 16px) * 1rem;
 }

Usage:

div {
 @include font-size(14px);
 }

box-shadow

This great mixin lets you specify the values of a box-shadow once, without worrying about vendor prefixes:

@mixin box-shadow( $h: 10px , $v: 10px , $b: 0px , $s: 0px , $c: #000000 ) {
     -webkit-box-shadow: $h $v $b $s $c;
 -moz-box-shadow: $h $v $b $s $c;
 box-shadow: $h $v $b $s $c;
 }

Usage:

div {
 @include box-shadow(8px, 8px);
 }

xPos

You can also use mixins to simplify syntax. This mixin provides a shorthand for positioning an element along the x axis:

@mixin xPos($x) {
 -webkit-transform:translateX($x);
 -moz-transform:translateX($x);
 -ms-transform:translateX($x);
 transform:translateX($x);
 }

Usage:

div {
 @include xPos(50px);
 }

vertical-align

Vertically aligning elements is challenging even with CSS, but this mixin gives you a nice simple solution:

@mixin vertical-align {
     position: relative;
 top: 50%;
 -webkit-transform: translateY(-50%);
 -ms-transform: translateY(-50%);
 transform: translateY(-50%);
 }

Usage:

div {
 @include vertical-align();
 }

flexbox

Sass mixins are great for handling settings like flexbox, that have had several different syntaxes published at different times.

@mixin flexbox
 {
 display:-webkit-box; // old
 display:-moz-box; // old
 display:-ms-flexbox; // ie
 display:-webkit-flex; // new
 display:flex; // new
 }

Usage:

div {
 @include flexbox();
 }

flex

Having set up a mixin to set the display property to flex, you’ll also need a mixin to set your flex value:

@mixin flex($values) {
     -webkit-box-flex: $values;
 -moz-box-flex:  $values;
 -ms-flex:  $values;
 -webkit-flex:  $values;
 flex:  $values;
 }

Usage:

div {
 @include flex(1, 2);
 }

flex-order

And another to set the order property:

@mixin flex-order($order){
     -webkit-box-ordinal-group: $order; // old
 -moz-box-ordinal-group: $order; // old
 -ms-flex-order: $order; // ie
 -webkit-order: $order; // new
 order: $order; // new
 }

Usage:

div {
 @include flex-order(3);
 }

flex-direction

Mixins also allow us to use Sass’ @if, @else if, and @else statements to combine what could have been two separate mixins into one:

@mixin flex-direction($direction)
 {
 @if $direction == column
 {
 -webkit-flex-direction:vertical;
 -moz-flex-direction:vertical;
 -ms-flex-direction:column;
 -webkit-flex-direction:column;
 flex-direction:column;
 }
 @else
 {
 -webkit-flex-direction:horizontal;
 -moz-flex-direction:horizontal;
 -ms-flex-direction:row;
 -webkit-flex-direction:row;
 flex-direction:row;
 }
 }

Usage:

div {
 @include flex-direction(column);
 }

gradient

We should always try to keep our code simple, but when necessary mixins can be huge. This mixin allows us to create different kinds of gradient for all browsers, using just three values:

@mixin gradient($start-color, $end-color, $orientation)
 {
 background: $start-color;
 @if $orientation == vertical
 {
 // vertical
 background: -moz-linear-gradient(top,  $start-color 0%, $end-color 100%);
 background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,$start-color), color-stop(100%,$end-color));
 background: -webkit-linear-gradient(top,  $start-color 0%,$end-color 100%);
 background: -o-linear-gradient(top,  $start-color 0%,$end-color 100%);
 background: -ms-linear-gradient(top,  $start-color 0%,$end-color 100%);
 background: linear-gradient(to bottom,  $start-color 0%,$end-color 100%);
 filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='$start-color', endColorstr='$end-color',GradientType=0 );
 }
 @else if $orientation == horizontal
 {
 // horizontal
 background: -moz-linear-gradient(left,  $start-color 0%, $end-color 100%);
 background: -webkit-gradient(linear, left top, right top, color-stop(0%,$start-color), color-stop(100%,$end-color));
 background: -webkit-linear-gradient(left,  $start-color 0%,$end-color 100%);
 background: -o-linear-gradient(left,  $start-color 0%,$end-color 100%);
 background: -ms-linear-gradient(left,  $start-color 0%,$end-color 100%);
 background: linear-gradient(to right,  $start-color 0%,$end-color 100%);
 filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='$start-color', endColorstr='$end-color',GradientType=1 );
 }
 @else
 {
 // radial
 background: -moz-radial-gradient(center, ellipse cover,  $start-color 0%, $end-color 100%);
 background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,$start-color), color-stop(100%,$end-color));
 background: -webkit-radial-gradient(center, ellipse cover,  $start-color 0%,$end-color 100%);
 background: -o-radial-gradient(center, ellipse cover,  $start-color 0%,$end-color 100%);
 background: -ms-radial-gradient(center, ellipse cover,  $start-color 0%,$end-color 100%);
 background: radial-gradient(ellipse at center,  $start-color 0%,$end-color 100%);
 filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='$start-color', endColorstr='$end-color',GradientType=1 );
 }
 }

Usage:

div {
 @include gradient(#ff00ff, #ff00cc, vertical);
 }

ghost-button

If you want to stay on-trend, you can use this mixin to create the ghost button we built a couple of weeks ago. The &:hover allows us to specify the hover state:

@mixin ghost-button($font, $font-size, $font-color, $border-size, $border-color, $padding, $transition-speed, $hover-color)
 {
 display:inline-block;
 text-decoration:none;
 text-transform:uppercase;
 font-family: $font;
 font-size: $font-size;
 color:$font-color;
 border:$border-size solid $border-color;
 padding:$padding;
 -webkit-transition: color $transition-speed, background $transition-speed;
 transition: color $transition-speed, background $transition-speed;
 &:hover
 {
 background:$border-color;
 color:$hover-color;
 }
 }

Usage:

div {
 @include ghost-button(“Trebuchet”, 12px, #ffffff, 5px, #34dec6, 4px, 300ms, #000000 );
 }

break-point

By using the @content statement, we can even pull in content, and set up all our break points by keyword. You shouldn’t set break points based on devices, but for the sake of clarity here’s one for desktop and mobile:

@mixin break-point($point)
 {
 @if $point == desktop{
 @media only screen and (max-width:50em)
 {
 @content;
 }
 }
 @else if $point == mobile{
 @media only screen and (max-width:20em)
 {
 @content;
 }
 }
 }

Usage:

div {
 margin:5em;
 @include break-point(mobile)
 {
 margin:2em;
 }
 }
By Paddi MacDonnell
Paddi MacDonnell is a designer and entrepreneur from Northern Ireland, follow her on Twitter.
  • http://dkampdesign.com/ Joshua Dorenkamp

    Nice collection!
    Since you are using a preprocessor anyway, I would recommend using Grunt and Autoprefixer to cut down on all those bloaty prefixes and eliminate the need for some of those

  • maxquattromani

    if you’re not a passing a parameter in your mixin, you can lose the parenthesis. for example: ‘@include flexbox;’ instead of ‘@include flexbox();’

    • Roy Tomeij

      And if you’re not using a parameter or @content block, like in this example, you should use @extend with a %placeholder instead of a mixin to prevent code bloat (or call @extend from the mixin if you think that’s cleaner).

  • http://hugogiraudel.com/ Hugo Giraudel

    Please don’t use Sass for prefixing or reming. It is not a good idea. Both should be done with a postprocessor, respectively Autoprefixer and px_to_rem for instance.

    Not only would it lighten the codebase a lot, but it also would make the code much more maintainable since it’s basically a configuration file (Gruntfile or whatever) that does the job.

    • Thomas Semmler

      Of course you are here! You throw the word “sass” out there and a wild Hugo Giraudel appears right afterwards. 😀

      I agree with you of course, but I just had to write this. 😀

    • Paddi

      That’s pretty questionable. I have no objection to post-processors if you’re working solo, but unlike preprocessors they’re not widely used and usually result in one more incompatibility for teams working remotely.

      There’s no reason that your mixins can’t be set up in a configuration file, and if they’re adding that much to your codebase there’s something fundamentally wrong with the way you’re writing CSS.

      For the vast majority of projects the benefits of streamlined workflow outweighs the downside of 2 or 3 extra lines in a .scss file.

      • haromaster

        You mention the benefits of ‘streamlined workflow’ but you would balk at extending that to a post-processing workflow among your team?. Seems counter intuitive.

        • Paddi

          The more technology you rely on, the less compatible you are with other processes.

          Even when I am in a position to choose to use a post-processor, I wouldn’t do so for 90% of the projects I work on. All you’re doing is raising the entry level for the person that has to maintain the project after I’ve moved on.

          If you’re talking about a single in-house team that you dictate to, then yes, obviously it’s worthwhile because you can set it up once and forget it.

          • LeeFloyd

            Learning pre-processing syntax is much harder for a novice to pick up than to “remember to run the magic voodoo after you make changes”.

      • Roy Tomeij

        If that’s your issue, I’d say you need better tooling to make sure everyone is on the exact same environment. You have the same issue with post-processors, making sure everyone is on the same version of (lib)Sass, etc.

        • Paddi

          Perhaps that’s the case for an in-house team. The reality of freelancing is that you rarely get to give input on processes, let alone dictate them. That’s especially true working remotely.

          Pre-processing is widely embraced, post-processing is not.

          The benefits of post-processing do not outweigh the downside of imposing a process on someone else that they’re not comfortable with. Especially as post-processing (or pre) offers no discernible benefit to the final product.

    • Daniel Tonon

      I’m in favour of not using auto-prefixing. I like knowing exactly what prefixes are going into my CSS so I have complete control over them.

      Also, doesn’t auto-prefixing completely ruin the CSS .map file? Chrome dev tools are able to read the CSS .map files and tell you exactly what line number and what scss file CSS rules originate from. This is SUPER useful but if the CSS is different to the CSS outputted at the time of SASS compilation then the map file gets completely out of synch and become useless to you.

      I would much rather keep my CSS map files in synch than have slightly more maintainable mixins that I practically never alter anyway.

      • artuska

        1) Completely weak argument. What bad will happen if there will be some few redundant prefixes in your CSS?

        2) Just do not use minified CSS for development, use it only on production, so you will never care about line numbers and .map files. Grunt+Compass will tell you about errors in .scss files. And, well, I have never needed .map files for my CSS in my entire life — what I’m doing wrong? Can you please show some use cases when I really can feel Autoprefixer drawbacks?

        • Daniel Tonon

          1) Loads of extra useless file size when you multiply those few extra pre-fixed rules out across a whole website. Since you don’t control the prefixes, it might not include prefixes that you want, or it might leave in extra prefixes in that aren’t necessary for your site adding to file size.

          2) I don’t minify my css in development, my argument (for this point anyway) has nothing to do with minification. I like having a way of, in my editor, jumping straight to the rule that I’m currently looking at in the browser dev tools. Since SASS rules are nested, I can’t just copy/paste the full rule from the browser dev tools into a finder window in my editor to jump to the line (that’s how I used to do it). I need to use line numbers instead now. Also, SASS files tend to be more modularised than css files so knowing which file to look in helps. Chrome dev tools are able to read the css .map files and tell me exactly what file I need to look in and exactly what line I need to go to. How can you possibly not see the usefulness in having a constant display of where to find your css rules in the sass files?

  • http://jamessteinbach.com/ James Steinbach

    I’d add that things like border-radius & box-shadow don’t need prefixes at all. The browsers that use those prefixes are so old & so rarely used (one-quarter to one-half of a percent of global usage), and corners & shadows should just be visual enhancement, not usability / accessibility requirements.

    Here’s my take on what not to use mixins for (spoiler: I’m also a big fan of Autoprefixer) -http://jamessteinbach.com/css/sass/stop-using-worthless-sass-mixins/

    • Paddi

      That’s true if you’re only supporting the very latest browsers. However, most clients still require IE8. Some even ask for IE7.

      In reality prefixes are an ugly necessity for the time-being.

      • http://jamessteinbach.com/ James Steinbach

        I understand old IE support and prefixes do matter (that’s why I recommend Autoprefixer), but my point about those two specific CSS properties still stands: IE7 & 8 won’t do border-radius or box-shadow *at all* no matter how many prefixes you use.

      • haromaster

        Prefixes are an ugly necessity in some cases, but I think @jdsteinbach:disqus’s point is touching more on including prefixes that don’t do anything and the benefit of auto-prexfing instead.

    • http://victorlava.com/ Victor Lava

      I don’t see a difference between 10kB bigger CSS file. Does it really makes a difference guys?

  • Paddi

    Disagree on post-processing (see above).

    However, you’re right about border-radius, I’ve asked for it to be changed to something more appropriate.

  • http://kevinoliveira.com.br/ Kevin Oliveira

    Great post, really! 😀

Home XML WordPress Web Services Web Development Web Design Underscore Uncategorized Tutorial Tools SQL Server Social Apps Snippet SEO Security RoR Responsive Design Resources Python PHP News MySQL Mobile Miscellaneous jQuery JavaScript Java J2EE HTML5 HTML Design Patterns