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.
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.