Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 298
Zeev Katz Avatar asked Nov 11 '16 14:11

Zeev Katz


People also ask

How do I make multiple transitions in CSS?

You can transition two (or more) CSS properties by separating them with a comma in your transition or transition-property property. You can do the same with duration, timing-functions and delays as well. If the values are the same, you only need to specify one of them.

How do you use transition properties?

The transition-timing-function property can have the following values: ease - specifies a transition effect with a slow start, then fast, then end slowly (this is default) linear - specifies a transition effect with the same speed from start to end. ease-in - specifies a transition effect with a slow start.


3 Answers

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

like image 188
Black Enigma Avatar answered Oct 16 '22 21:10

Black Enigma


Since this is the first result on Google, I want to say that this does not solve my problem. I wanted to transition multiple properties, with only one mixin. I came up with this solution: (see link for helper functions)

/*
  usage: @include transition(prop1, prop2, ..., 0.5s cubic-bezier(0.16, 0.85, 0.45, 1));
*/
@mixin transition($args...) {
  $type: nth($args, length($args));
  $props: remove-nth($args, length($args));
  $result: ();

  @for $i from 1 through length($props) {
    $prop: nth($props, $i);
    $result: append($result, $prop);
    $result: append($result, $type);
    @if $i != length($props) {
      $result: append($result, unquote($string: ","));
    }
  }

  @include simple_transition($result);
}
like image 28
yspreen Avatar answered Oct 16 '22 19:10

yspreen


I created a short mixin that allows adding multiple transition properties in one declaration. In case number of arguments provided for the timing, easing or delay, is less than number of transition properties, the arguments are repeated.

@mixin transition($prop, $time, $easing: $ease1, $delay: 0s) {
    $transition: ();
    @for $i from 1 through length($prop) {
        @for $j from 0 to (length($prop)) - (length($time)) {
            $time: join($time, nth($time, -1));
        }
        @for $j from 0 to (length($prop)) - (length($easing)) {
            $easing: join($easing, nth($easing, -1));
        }
        @for $j from 0 to (length($prop)) - (length($delay)) {
            $delay: join($delay, nth($delay, -1));
        }

        $transition: append(
            $transition,
            (nth($prop, $i) nth($time, $i) nth($easing, $i) nth($delay, $i)),
            $separator: comma
        );
    }
    transition: $transition;
}

//scss input:
@include transition(height width transform, 0.2s 0.3s, linear, 0s);

//css output:
transition: height 0.2s linear 0s, width 0.3s linear 0s, transform 0.3s linear 0s;
 
like image 3
nidhishs06 Avatar answered Oct 16 '22 20:10

nidhishs06