home about me

Short and useful SCSS Mixins

With CSS getting more and more features, SCSS has less use cases. Yet there are still a lot of areas where SCSS makes development easier.

Unpacking Shorthands

To use mixins the same way you use CSS shorthand assignments, a helper function can unpack the provided parameters:

@function unpack-shorthand($shorthand) {
  @if length($shorthand) == 1 {
    @return nth($shorthand, 1) nth($shorthand, 1) nth($shorthand, 1) nth($shorthand, 1);
  } @else if length($shorthand) == 2 {
     @return nth($shorthand, 1) nth($shorthand, 2) nth($shorthand, 1) nth($shorthand, 2);
  } @else if length($shorthand) == 3 {
     @return nth($shorthand, 1) nth($shorthand, 2) nth($shorthand, 3) nth($shorthand, 2);
  } @else {
     @return $shorthand;
  }
}

It’s verbose, but it takes care of expanding lists like 20px auto to 20px auto 20px auto. This way mixins can be used just like real CSS shorthands, for example margin: 0 auto, which expands to margin: 0 auto 0 auto.

Size and Position

This one is a matter of personal preference, but I prefer sorting attributes alphabetically. It’s easy to remember, easy to automate, and there are no discussions to be had.

But the ugly downside of using alphabetical sorting is that attributes that belong together might end up quite some lines apart - for example height and width. This is why I prefer using simple mixins for setting the size of elements:

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

// usage:
.c-image {
  @include size(100%, auto);
}

// you can also just use one parameter
.c-box {
  @include size(50px); // sets width and height
}

For the position, I use a slightly more complex mixin:

@mixin position($position, $box-edge-values) {
  position: $position;
  $box-edge-values: unpack-shorthand($box-edge-values);
  top:    nth($box-edge-values, 1);
  right:  nth($box-edge-values, 2);
  bottom: nth($box-edge-values, 3);
  left:   nth($box-edge-values, 4);
}

// usage
.c-stickyHeader {
  @include position(fixed, 0 0 auto 0);
}

.c-modal {
  @include position(absolute, 20%); // 20% distance to each side
}

Z-Index

My favorite of the list. A small mixin to set the z-index of an element based on an array of layers. This way you will never, ever have to deal with manually coming up with z-index values ever again:

$z-index-list: (
  'base',
  'header',
  'modal',
  'tooltip',
);

@mixin z-index($layer) {
  // we're adding 1 so the first layer starts at 2,
  // one above the "standard" z-index of 1.
  // SCSS array indizes start at 1
  z-index: #{index($z-index-list, $layer) + 1};
}

// usage
.c-modal {
  @include z-index('modal');
}

Bonus points if you configure your linter to disallow providing numbers for z-index.