Quick Fix: Sass Mixins for rem Values with px Fallback

Rems are awesome. They allow us to circumvent the complex cascading em mess that even great frond-end developers find ourselves in at times. The problem with them is figuring out the corresponding px value and remembering to put in the fallback. I’ve adapted a mixin by Karl Merkli to do just that. This beautiful little chunk of Sass will take rem value input in two different formats (with or without unit values) and output both the px and rem values you need.

// Values for property in REM and PX with 1rem = 16px adapted from mixin by Karl Merkli
// @inlcude rem-px(STRING PROPERTY, REMVAL1, REMVAL2, REMVAL3, REMVAL4)
// @inlcude rem-px(margin, 1, 1, 2, 1.5) outputs or
// @include rem-px(margin, 1rem, 1rem, 2rem, 1.5rem) outputs:
// margin: 16px 16px 32px 24px;
// margin: 1rem 1rem 2rem 1.5rem;
@function strip-unit($num) {
    @return $num / ($num * 0 + 1);
}

@mixin rem-px($property, $values...) {
    $max: length($values);
    $pxValues: '';
    $remValues: '';

    @for $i from 1 through $max {
        $value: strip-unit(nth($values, $i));

        @if $value != 0 {
            $pxValues: #{$pxValues + $value*16}px;
        } @else {
            $pxValues: #{$pxValues + $value*16};
        }

        @if $i < $max {
            $pxValues: #{$pxValues + " "};
        }
    }

    @for $i from 1 through $max {
        $value: strip-unit(nth($values, $i));

        @if $value != 0 {
            $remValues: #{$remValues + $value}rem;
        } @else {
            $remValues: #{$remValues + $value};
        }

        @if $i < $max {
            $remValues: #{$remValues + " "};
        }
    }

    #{$property}: $pxValues;
    #{$property}: $remValues;
}

That’s nice, but sometimes trying to figure out what rem value you need is difficult. Sometimes I just want to say, “Give me 2 #*@!$&^ px of padding!” I’ve also written the mixin above to take px value input.

Note this one uses the strip-unit function in above the first mixin, so make sure you copy/paste that function if you’re only using this mixin.

// Values for property in REM and PX with 16px = 1rem adapted from mixin by Karl Merkli
// @inlcude px-rem(STRING PROPERTY, PXVAL1, PXVAL2, PXVAL3, PXVAL4)
// @inlcude px-rem(margin, 16, 16, 32, 24) or
// @include px-rem(margin, 16px, 16px, 32px, 24px) outputs:
// margin: 16px 16px 32px 24px;
// margin: 1rem 1rem 2rem 1.5rem;
@mixin px-rem($property, $values...) {
    $max: length($values);
    $pxValues: '';
    $remValues: '';

    @for $i from 1 through $max {
        $value: strip-unit(nth($values, $i));

        @if $value != 0 {
            $pxValues: #{$pxValues + $value}px;
        } @else {
            $pxValues: #{pxValues + $value};
        }

        @if $i < $max {
            $pxValues: #{$pxValues + " "};
        }
    }

    @for $i from 1 through $max {
        $value: strip-unit(nth($values, $i));

        @if $value != 0 {
            $remValues: #{$remValues + $value/16}rem;
        } @else {
            $remValues: #{$remValues + $value};
        }

        @if $i < $max {
            $pxValues: #{$pxValues + " "};
        }
    }

    #{$property}: $pxValues;
    #{$property}: $remValues;
}

There you go! They’re simple and will really help your workflow if you’re a user of rems. They also use a body font size of 100% (16px), so none of the base 10 resizing to mess up the rest of your stylesheet.

Of course you can find all my mixins in my WordPress Boilerplate, Squeaky Clean.

Also, if you haven’t read it, I’ve written down my Sass, Less, and CSS best practices in another post.

What Sass mixins do you find really useful?