search home list

An improved Sass rem mixin for unitless numbers

Since we started using Sass in our projects here at intuio, our workflow has improved a lot. There are a lot of useful mixins out there, let alone the comprehensive compass mixins library. Given the fact that most of our projects are to be designed responsive, we do only use relative sizing units. While ’em’ units can cause a lot of headache because it’s up to you to always calculate the desired values, ‘rem’ units are a great relief for every designer.

As Jonathan Snook explained before, using ‘rem’ with a ‘px’ fallback is perfectly fine for all major browsers (including IE8) and there is a nice mixin for setting the font-size by Chris Coyier. Heck, there’s even a very similar mixin published by bitmanic but none of these perfectly fit our needs. We love to work with unitless variables, which is why I created (yet) another mixin that covers just that coding style. Lets dig into some code…

Assumptions

There are a couple of assumptions:

$htmlFontSize: 62.5%; // Set the font-size to 10px
$bodyFontSize: 1.6; // Unitless number, equals 16px

The @mixin

So far so good, now let’s look at the mixin.

// Mixin that allows to specify arbitrary CSS properties with
// unitless numbers. The output has rem unit with pixel fallback.
// Shorthand assignments are supported too!
$base_line: 10;

@mixin rem($property, $values)
{
  // Placeholder variables
  $shorthand_px:  "";
  $shorthand_rem: "";

  // Parameter $values might be a list of elements
  @each $value in $values
  {
    // Current value is a valid number and greater than 0
    @if $value != auto and $value != 0
    {
      // Add 'px' and 'rm' to the current value and store in
      // placeholder variables
      $shorthand_px: #{ $shorthand_px + " " + $value * $base_line + px };
      $shorthand_rem: #{ $shorthand_rem + " " + $value + rem };
    }
    // Current value is 'auto' or 0
    @else
    {
      // Add only 'auto' or 0 to the placeholder variables
      $shorthand_px: #{ $shorthand_px + " " + $value };
      $shorthand_rem: #{ $shorthand_rem + " " + $value };
    }
  }

  // Output the CSS property in pixels and rems
  #{$property}:$shorthand_px;
  #{$property}:$shorthand_rem;
}

Usage

body
{
  @include rem(font-size, $bodyFontSize);
  @include rem(padding, 0 $bodyFontSize);
}

.wrapper
{
  @include rem(margin, 0 auto $bodyFontSize);
}

Output


body
{
  font-size:16px;
  font-size:1.6rem;

  padding:0 16px;
  padding:0 1.6rem;
}

.wrapper
{
  margin:0 auto 16px;
  margin:0 auto 1.6rem;
}

Conclusion

So, if you’re working with unitless number as we do, this little mixin might come in handy. I am sure there is room for improvement and I would love to hear any suggestions. Happy coding!

Show all articles

2 Responses

  1. Steve says:

    Love this solution, means I can use rems for margin, padding, font-size etc. with a nice pixel fallback. The only issue I’ve found is that it doesn’t work with !important?

  2. Hi Steve, thanks for your reply.
    You’re correct, the mixin does not support the !important keyword. You should always try and avoid it completely but I know there are situations you really need it.
    I’ve updated the mixin some time ago before we released it together with our complete framework http://awesomeness.intuio.at
    It now supports the !important keyword, check it out here: https://gist.github.com/xonic/11032959
    Thanks.

What do you think?