Multiple transitions with scss

Zeev Katz picture Zeev Katz · Nov 11, 2016 · Viewed 13.4k times · Source

I have a multiple transition problem with scss @mixin. Im trying to create dynamic transition @mixin with 1-5 different properties. When I'm processing the code below this error shows up:

Error: Mixin transition takes 1 argument but 3 were passed. on line 758 of style.scss, in `transition' from line 758 of style.scss Use --trace for backtrace.

This is my code:


@mixin:

@mixin transition($x){
    transition: $x;
    -webkit-transition: $x;
    -moz-transition: $x;
    -ms-transition: $x;
    -o-transition: $x;
}

@include:

@include transition(visibility 0s ease 0.2s, opacity 0.2s ease, transform 0.3s ease);

I figured it out with this hack but it looks like a very unclean solution to me:

@include transition(visibility 0s ease 0.2s + "," + opacity 0.2s ease + "," + transform 0.3s ease);

Is there a better way to do it?

Answer

Black Enigma picture Black Enigma · Nov 11, 2016

In your mixin, you have declared a single variable $x as a parameter which means that sass expects the mixin to be called with one argument.

@include transition(visibility 0s ease 0.2s)

When you pass the mixin comma separated values, it causes an error because sass sees these as multiple values instead of a single value which it expects.

@include transition(visibility 0s ease 0.2s, opacity 0.2s ease) //Sees two args instead of one arg

In Sass, comma separated values can be interpreted as a single value if declared as varargs. Varargs are mixin or function parameters declared with 3 dots appended to their name.

Replacing your $x parameter with $x... will ensure that sass interprets the comma separated arguments passed to your mixin as one value.

@mixin transition($x...){
  -webkit-transition: $x;
  -moz-transition: $x;
  -ms-transition: $x;
  -o-transition: $x;
  transition: $x;
}

It can then be used like this

div {
  @include transition(color 1s, background-color 1s, border-color 1s);
}

which compiles to

div {
  -webkit-transition: color 1s, background-color 1s, border-color 1s;
  -moz-transition: color 1s, background-color 1s, border-color 1s;
  -ms-transition: color 1s, background-color 1s, border-color 1s;
  -o-transition: color 1s, background-color 1s, border-color 1s;
  transition: color 1s, background-color 1s, border-color 1s;
}

By doing this you can pass the values as you normally would in CSS without the hack you are currently using making it much cleaner.

Hope this helps