10 Awesome SASS (SCSS) Mixins
Tags: css, sass, scss, webdev
Published: 2020-02-19 14:07:38

<h2>Introduction</h2>

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

This is a collection of powerful sass (scss) mixins that we used the most at [Jam3](https://jam3.com) 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.

<ul>
<li><a href="#box">1. Box</a></li>
<li><a href="#flexbox">2. Flexbox Toolkit</a></li>
<li><a href="#font-size">3. Font Size</a></li>
<li><a href="#font-face">4. Font Face</a></li>
<li><a href="#cover-background">5. Cover Background</a></li>
<li><a href="#pseudo">6. Pseudo</a></li>
<li><a href="#media-queries">7. Media queries</a></li>
<li><a href="#zindex">8. z-index handling</a></li>
<li><a href="#visibility">9. Visibility</a></li>
<li><a href="#background-transition">10. Background Transition</a></li>
</ul>

---

<h2>Let's dive into detail</h2>

<h3 id="box">1. Box</h3>

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

```scss
@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);
}
```

---

<h3 id="flexbox">2. Flexbox Toolkit</h3>

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.

```scss
@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;
}
```

⚠️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:

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

.horizontally-centered-element {
  flex-direction: column;
  @include flex-center-vert;
}
```

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

---

<h3 id="font-size">3. Font Size</h3>

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.

```scss
@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;
}
```

---

<h3 id="font-face">4. Font Face</h3>

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.

```scss
@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);
```

---

<h3 id="cover-background">5. Cover Background</h3>

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

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

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

---

<h3 id="pseudo">6. Pseudo</h3>

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;

```scss
@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);
  }
}
```

---

<h3 id="media-queries">7. Media queries</h3>

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

```scss
$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;
  }
}
```

---

<h3 id="zindex">8. z-index handling</h3>

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.

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

@mixin z-index($id) {
  z-index: index($elements, $id);
}
```

⚠️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

```scss
.div1 {
  z-index: 2;

  .child {
    z-index: 5000;
  }
}

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

💻Here is an example:

{% codepen https://codepen.io/alemesa/pen/bGdVyEv %}

⚠️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.

---

<h3 id="visibility">9. Visibility</h3>

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

```scss
@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;
  }
}
```

---

<h3 id="background-transition">10. Background Transition</h3>

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.

```scss
@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;
    }
  }
}
```

💻Here is an example of this mixin:

{% codepen https://codepen.io/alemesa/pen/XWbXLNK %}

<h2>Conclusion</h2>

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

{% codepen https://codepen.io/alemesa/pen/RwPRdBx %}

<h2>References | Useful Links</h2>

- [Sass Documentation](https://sass-lang.com/documentation)
- [Bourbon Tool Set](https://www.bourbon.io/) - Huge library with extra scss tools

<h2>Collaborators</h2>

All the people at [Jam3](https://jam3.com) that at some point touched these mixins.