csssassdryscss-mixins

How do I create a comma separated list from mixin's arguments?


To avoid boilerplate, I want to write a function/mixin taking a list of CSS properties (at least one) and write the same transition for each, and also output will-change accordingly. Given margin-left, width, to output:

{
  transition: margin-left $some-value, width $some-value;
  will-change: margin-left, width;
}

I found I can use an arguments list with a spread operator (@mixin some-mixin($args...)) and tried looping using @each, but I don't really know how to use @each inside a single property and concatenate the results with a comma, without having an end comma.


Solution

  • Here is the github comment which led me to the answer.


    There is a function called append in 'sass:list', which can be used to create a comma separated list, as follows:

    @use "sass:list";
    
    $timing: 0.42s cubic-bezier(0.4, 0, 0.2, 1);
    
    @mixin transition($args...) {
      $tr: ();
      $wc: ();
      @each $arg in $args {
        $tr: append($tr, append($arg, $timing, space), comma);
        $wc: append($wc, $arg, comma);
      }
      transition: $tr;
      will-change: $wc;
    }
    

    Input (SCSS):

    .foo {
      @include transition(width, margin-left);
    }
    .bar {
      @include transition(transform);
    }
    

    Output (CSS):

    .foo {
      transition: width 0.42s cubic-bezier(0.4, 0, 0.2, 1), margin-left 0.42s cubic-bezier(0.4, 0, 0.2, 1);
      will-change: width, margin-left;
    }
    
    .bar {
      transition: transform 0.42s cubic-bezier(0.4, 0, 0.2, 1);
      will-change: transform;
    }
    

    See it working in SASS: Playground.