csssassvendor-prefix

Multiple transitions with scss


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?


Solution

  • 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