Search code examples
sassmixins

Handling optional arguments in a Sass mixin


I'm just getting started with Sass so bear with me.

I have this mixin to handle declaring font sizes in both px (for old IE) and rem for modern browsers, it also does a nice line-height calculation.

@mixin font-size($font-size, $line-height-val: "", $sledge-hammer: "" /* $sledge-hammer is    for an optional `!important` keyword */) {
    font-size: ($font-size)+px#{$sledge-hammer};
    font-size: ($font-size / $base-font-size)+rem#{$sledge-hammer};
    @if $line-height-val == "" {
          line-height: ceil($font-size / $base-line-height) * ($base-line-height / $font-size);
    } @else {
          line-height: #{$line-height-val};
    }
}

It works but I feel like the optional arguments ($line-height-val and $sledge-hammer) is not the most optimal way of doing it. $line-height-val is needed as sometimes I need to manually declare the line-height and $sledge-hammer is needed because I need to declare the !important keyword on some of my helper classes.

90% of the time I just use the mixin like this:

@include font-size(24);

Which compiles too:

font-size: 24px;
font-size: 1.5rem;
line-height: 1.1;

When I need to override the line-height I do this:

@include font-size(24, 1.6);

Which compiles too:

font-size: 24px;
font-size: 1.5rem;
line-height: 1.6;

But if I need to declare the !important keyword then I have to do this:

@include font-size($font-size-sml, "", !important);

Which compiles too:

font-size: 15px!important;
font-size: 0.9375rem!important;
line-height: 1.6;

But feels funny I have to use empty "" for the 2nd argument, and the value for the 3rd argument will always be !important so that should be in the mixin?

I just wonder if there's a much cleaner way of writing this mixin?


Solution

  • You can specify the parameters when you call them like this:

    @include font-size($font-size-sml, $sledgehammer: !important);
    

    You could shorten the mixin arguments like this:

    @mixin font-size($font-size, $line-height-val: "", $i: false /* flag for`!important` */) {
        $important: if($i, "!important", "");
        font-size: ($font-size)+px #{$important};
        font-size: ($font-size / $base-font-size)+rem #{$important};
        @if $line-height-val == "" {
              line-height: ceil($font-size / $base-line-height) * ($base-line-height / $font-size);
        } @else {
              line-height: #{$line-height-val};
        }
    }