0

I have the following mixin:

.transition (@property, @duration: 0.2s) {
    -webkit-transition: @property @duration ease-in-out;
       -moz-transition: @property @duration ease-in-out;
        -ms-transition: @property @duration ease-in-out;
         -o-transition: @property @duration ease-in-out;
            transition: @property @duration ease-in-out;
}

How can I change the mixin to allow multiple properties (i.e. background and color transition)?

  • possible duplicate of [Using undefined number of arguments in mixins](http://stackoverflow.com/questions/11013528/using-undefined-number-of-arguments-in-mixins) – Harry Jan 23 '15 at 02:49

3 Answers3

1

There a lot of similar Q&A here at SO already (for instance) but since most of those are full of really outdated (mis)information and hacks it would make sense to write a new answer I guess:

-

Well, you need to decide if you want the mixin to detect each property value as an individual argument (with optional default value) or just pass them all together (these are sort of incompatible requirements, it's still possible to combine them though - see later).

In the simplest case the mixin should be defined just as:

.transition(@values) {
    transition: @values;
}

Nothing more than that, and used like this:

.transition(width);
.transition(color 0.2s ease-in-out);
.transition(opacity 2s ease-in, height 5s ease-out;);
// etc.

See the documetation about using comma separated list as mixin arguments.

-

Now about single values as individual mixin parameters and default options. (Honestly for me this tendency to blindly put some pretty random default value for every singe parameter of every singe mixin looks like a common anti-pattern but either way). As you may notice the above mixin definition does not let you to specify a default value for individual parameters. Obviously if you define your mixin as:

.transition(@property, @duration: 0.2s, @timing: ease-in-out) {
    transition: @arguments;
}

(or similar) it cannot handle multiple properties anymore (@duration and @timing won't match corresponding arguments no matter what syntax you use to call it (with just a few specific exceptions). E.g. .transition(opacity 2s ease-in, height 5s ease-out;); would result in transition: opacity 2s ease-in, height 5s ease-out 0.2s ease-in-out; etc. which does not make any sense)

So if you still need both (yet again not counting this often makes such mixin usage uncertain and confusing) you have to invent some way to handle both variants somehow. For instance the simplest method (just one of literally zillion possible variants) would be just to provide different definitions for different number of values in the first argument (see conditional mixins), e.g.:

.transition(@property, @duration: 0.2s, @timing: ease-out)
    when (length(@property) = 1)  {
        transition: @arguments;
}

.transition(...) when (default()) {
    transition: @arguments;
}

With usage being the same as above except .transition(width); (and similar stuff) now has different result.

-

And as always, regardless of all above if it's only about writing vendor-prefixing mixins (and I guess it is) - just stop doing that.

Community
  • 1
  • 1
seven-phases-max
  • 11,765
  • 1
  • 45
  • 57
0

This ought to work:

.transition (@property; @duration: 0.2s) {
    -webkit-transition-property: @property;
       -moz-transition-property: @property;
         -o-transition-property: @property;
            transition-property: @property;
    -webkit-transition-duration: @duration;
       -moz-transition-duration: @duration;
         -o-transition-duration: @duration;
            transition-duration: @duration;
        -webkit-timing-function: ease-in-out;
           -moz-timing-function: ease-in-out;
             -o-timing-function: ease-in-out;
                timing-function: ease-in-out;
}

.test {
  .transition(color, background; 3s)
}

The biggest trick here is using a semicolon as a delimiter for the mixin, so that we can use the comma as delimiter for the transition-property. Also, you don't need the -ms- prefix, IE never had it for transitions.

-1

Why not like this?

Mixin:

.transition(@transition) {
  -webkit-transition: @transition;
       -o-transition: @transition;
          transition: @transition;
}

and use it: for example: .transition(~"color ease-in-out 1s, background-color ease-in .5s");

Hope it helps

quarky
  • 710
  • 2
  • 13
  • 36