DEV Community

Cover image for 10 Awesome SASS (SCSS) Mixins
Alejandro Mesa
Alejandro Mesa

Posted on • Updated on

10 Awesome SASS (SCSS) Mixins

Introduction

First post, here I go!! 🚀 give me hell 🔥.

This is a collection of powerful sass (scss) mixins that we used the most at Jam3 and some others I found to be useful. Mixins are pretty much functions that return css chunks, they are very powerful, make the code cleaner and will speed up your development process. These are not just for sass, for example, css-in-js fans could just create helper functions with these.

| You can skip ahead using this menu.


Let's dive into detail

1. Box

Let's start with a simple but popular one to define width and height in one go.

@mixin box($width, $height: $width) {
  width: $width;
  height: $height;
}

/* ===== Usage ===== */
div {
  // You can pass width && height
  @include box(200px, 300px);
  /* or just pass width and the height
     will default to the width value */
  @include box(200px);
}
Enter fullscreen mode Exit fullscreen mode

2. Flexbox Toolkit

Flexbox has taken over the front-end layout together with css grid. These are a set of mixins to quickly develop with it, the names are pretty self-descriptive and I highly use them because I always forget which one represents the main axis and which one the cross axis.

@mixin flex-column {
  display: flex;
  flex-direction: column;
}

@mixin flex-center {
  display: flex;
  align-items: center;
  justify-content: center;
}

@mixin flex-center-column {
  @include flex-center;
  flex-direction: column;
}

@mixin flex-center-vert {
  display: flex;
  align-items: center;
}

@mixin flex-center-horiz {
  display: flex;
  justify-content: center;
}
Enter fullscreen mode Exit fullscreen mode

⚠️One warning is that since flexbox works as an axis and basis system, if the flex direction changes we're swapping the axis therefore you will need to use the opposite, for example:

/* ===== Usage ===== */
.vertical-centered-element {
  @include flex-center-vert;
}

.horizontally-centered-element {
  flex-direction: column;
  @include flex-center-vert;
}
Enter fullscreen mode Exit fullscreen mode

💡As a practice, you could try building the css grid equals of these.


3. Font Size

This is one of my favorites because it keeps the code cleaner by shaving 2 lines off from multiple places. It sets font-size, line-height and letter-spacing in one go and defaults to normal for line-height and letter-spacing. It also keeps line-height unitless which I like.

You could adapt these mixins according to the type of units you work with, for example, you could make this work with a rem based font system.

@mixin font-size($font-size, $line-height: normal, $letter-spacing: normal) {
  font-size: $font-size * 1px;
  // font-size: $font-size * 0.1rem;
  // example using rem values and 62.5% font-size so 1rem = 10px

  @if $line-height==normal {
    line-height: normal;
  } @else {
    line-height: $line-height / $font-size;
  }

  @if $letter-spacing==normal {
    letter-spacing: normal;
  } @else {
    letter-spacing: #{$letter-spacing / $font-size}em;
  }
}

/* ===== Usage ===== */
p {
  @include font-size(12, 18, 1.2);
  // returns
  font-size: 12px;
  line-height: 1.5; // 18 / 12
  letter-spacing: 0.1em;
}
Enter fullscreen mode Exit fullscreen mode

4. Font Face

This is just to quickly add font-face with all sources ( Embedded OpenType, WOFF, TrueType, and SVG) in one command, very useful for big sites with multiple font types and weights.

@mixin font-face($font-name, $path, $weight: normal, $style: normal) {
  @font-face {
    font-family: quote($font-name);
    src: url($path+".eot");
    src: url($path+".eot?#iefix") format("embedded-opentype"), url($path+".woff")
        format("woff"), url($path+".ttf") format("truetype"), url($path+".svg##{$font-name}")
        format("svg");
    font-weight: $weight;
    font-style: $style;
  }
}

/* ===== Usage ===== */
@include font-face(Roboto, "./assets/Roboto", normal, normal);
Enter fullscreen mode Exit fullscreen mode

5. Cover Background

Saving two lines again 😄 this time to add a cover background to an element

@mixin cover-background {
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center;
}

/* ===== Usage ===== */
div {
  background-image: url("cute-doggo.png");
  @include cover-background;
}
Enter fullscreen mode Exit fullscreen mode

6. Pseudo

This is a mixin that I use a lot for image masking but the idea is mostly to reduce lines since there is a lot of repetition when doing pseudo-elements;

@mixin pseudo(
  $width: 100%,
  $height: 100%,
  $display: inline-block,
  $pos: absolute,
  $content: ""
) {
  content: $content;
  display: $display;
  position: $pos;
  @include box($width, $height);
}

/* ===== Usage ===== */
div {
  position: relative;
  width: 200px;
  height: 200px;

  &:after {
    @include pseudo(100px, 100px);
  }
}
Enter fullscreen mode Exit fullscreen mode

7. Media queries

Since I have to google the @media syntax every single time, this mixin comes in handy to handle breakpoints, add more as needed.

$tablet: 768;
$large: 1024;
$desktop: 1280;

@mixin tablet {
  @media only screen and (min-width: $tablet * 1px) {
    @content;
  }
}

@mixin large {
  @media only screen and (min-width: $large * 1px) {
    @content;
  }
}

@mixin desktop {
  @media only screen and (min-width: $desktop * 1px) {
    @content;
  }
}

/* ===== Usage ===== */
h1 {
  font-size: 10px;

  @include tablet {
    font-size: 12px;
  }

  @include desktop {
    font-size: 20px;
  }
}
Enter fullscreen mode Exit fullscreen mode

8. z-index handling

Very straightforward mixin to control all the z-indexes from a central place.

  • First, we have to define all elements in an array where the priority increases to the right
  • Second, we use the index scss utility function to find the index of that array.

Pretty simple.

$elements: landing, header, modal, very-important-modal;

@mixin z-index($id) {
  z-index: index($elements, $id);
}
Enter fullscreen mode Exit fullscreen mode

⚠️As you might be thinking right now, this won't fix all your problems since z-index respects the stacking order of elements, for example in this case below div2 will still be on top of div1 > child but is a decent solution

.div1 {
  z-index: 2;

  .child {
    z-index: 5000;
  }
}

.div2 {
  z-index: 3; // This will still show on top of div1 > child
}
Enter fullscreen mode Exit fullscreen mode

💻Here is an example:

⚠️Also, z-index only works on positioned elements, so if everything in your website is static which is unlikely then it's all good and this mixin will be pure gold, if not, you must be careful and check the stacking of your elements.


9. Visibility

Quick mixin to hide or show an element, useful for fade in/out animations

@mixin fade($type) {
  @if $type== "hide" {
    visibility: hidden;
    opacity: 0;
    transition: visibility 1s, opacity 1s;
  } @else if $type== "show" {
    visibility: visible;
    opacity: 1;
    transition: visibility 1s, opacity 1s;
  }
}
Enter fullscreen mode Exit fullscreen mode

10. Background Transition

This one is more of a fun mixin, not highly reusable but I like this transition in buttons and is a way to show the power of mixins and encourage you to build your own and go a bit wild.

@mixin skew-background-transition($initial, $hover, $inverted: false) {
  background: linear-gradient(
    90deg,
    $hover 0%,
    $hover 50%,
    $initial 50%,
    $initial 100%
  );
  background-repeat: no-repeat;
  background-size: 200% 100%;

  background-position: right bottom;
  @if $inverted {
    background-position: left bottom;
  }
  transition: background-position 0.25s ease-out;

  &:hover {
    background-position: left bottom;
    @if $inverted {
      background-position: right bottom;
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

💻Here is an example of this mixin:

Conclusion

I hope you find some of these mixins useful. You should challenge yourself to create new ones depending on your requirements. As a good rule of thumb if you're repeating yourself more than times this is probably a good opportunity to check if a mixin could solve this. Since mixins could drastically change because of their opinionated nature you should make sure that your team is on board with the syntax and details.

I also put together everything that we covered in this article in this codepen as a playground in case you lovely people want to play around

References | Useful Links

Collaborators

All the people at Jam3 that at some point touched these mixins.

Discussion (9)

Collapse
simeon4real profile image
Simeon Udoh

Very insightful post Alejandro! I'll try out some of your mixins. I currently use a reset mixin. It helps me with a reset every time I start a new project.

@mixin reset {
margin: 0;
padding: 0;
box-sizing: inherit;
}

Then I just set box sizing via html. {}.

Collapse
alemesa profile image
Alejandro Mesa Author

Thank you! I have definitely seen this one. I do something similar in my global styles:

html {
  box-sizing: border-box;

  *,
  *::before,
  *::after {
    box-sizing: inherit;
  }

  // All html elements that I need to reset
  h1, h2, h3, h4, h5, h6, p, ul, ol {
    padding: 0;
    margin: 0;
  }
}

Another option is too use a css reset file, this one is pretty good dev.to/hankchizljaw/a-modern-css-r... by @hankchizljaw

Collapse
ronakjethwa profile image
Ronak Jethwa

How about these for the font-sizes?

$font-sizes: [20px, 22px, 24px, 26px, 28px, 30px, 36px, 40px, 50px];
@each $size in $font-sizes {
  .is-#{$size} {
    font-size: $size;

    @if $size > 35 {
      line-height: $size - 5px;
    }
  }
}
Enter fullscreen mode Exit fullscreen mode
Collapse
jslim profile image
José Delgado

Amazing!, thanks a lot!.

Collapse
eekayonline profile image
Edwin Klesman

Very nice set of mixins Alejandro, love it! Bookmarked for my next project 🙌🏻

Collapse
alemesa profile image
Alejandro Mesa Author

I'm glad it was useful 🤜🤛

Collapse
adahyto profile image
Adam

Very useful, thanks!

Collapse
joseluisrnp profile image
José Luis Recio

Nice mixins Alejandro! Thanks for share

Collapse
li profile image
Wenchen "Neo" Li

spinthink