So I'm trying to do something functionally equivalent to this:
Can a sass #mixin accept an undefined number of arguments?
...with a transitionFast mixin, but I want to be strict about the easing functions and speeds, so I've defined them within the mixin, like so:
#mixin transitionFast($property) {
-webkit-transition:$property ease 0.2s;
-moz-transition:$property ease 0.2s;
-o-transition:$property ease 0.2s;
transition:$property ease 0.2s;
}
How can I pass multiple $properties to this, without passing through the ease 0.2s part? I've tried this:
#mixin transitionFast($properties...) {
#each $property in $properties {
transition:$property ease 0.5s;
}
}
which I'm trying to call like this:
#include transitionFast(background-color, color);
but it doesn't work and only applies the transition to the last passed argument. Any ideas?
In your case there are several ways to go with sass splat-like args:
1) If you define mixin with splat args like so:
#mixin transitionFast($properties...) {
# with iteration on $properties
}
And you include it normal like this:
#include transitionFast(firstArg, secondArg, thirdArg);
Then you get
# compiled
transition: firstArg;
transition: secondArg;
transition: thirdArg;
2) You will also get the same thing when you don't specify splat args
#mixin transitionFast($properties) {
# with iteration on $properties
}
And include them with double parents
#include transitionFast((firstArg, secondArg, thirdArg));
3) If you declare mixin this way:
#mixin transitionFast($properties...) {
# with iteration on $properties
}
and call it whis way:
#include transitionFast(( background-color, color, red ));
you will get behavior similar to default behavior (ie without iteration over splat):
transition: background-color, color, red;
Now, back to your question, you can do this to get what You want:
$ease: ease 0.5s;
#mixin transitionFast($properties...) {
#each $prop in $properties {
transition: $prop $ease;
}
}
html {
#include transitionFast( background-color, color, margin );
}
Edit: instead transition: $prop $ease; go with compass #include transition( $prop $ease ); as Pik_at suggested, its more dry and sexy.
Just for fun:
If you leave (above) mixin as it is and include it like this:
#include transitionFast(( background-color, color ), padding);
it compiles to
transition: background-color, color ease 0.5s;
transition: padding ease 0.5s;
combining iteration and regular 'splatting', very cool stuff :)
Array parameters should be on bracket like:
#include transitionFast((background-color, color));
I made a simple code test to show you:
http://codepen.io/pik_at/pen/wBjgpY
Likewise, using Compass would help you to add transition mixin with browsers prefix:
#mixin transitionFast($properties) {
#each $property in $properties {
#include transition($property 2s ease);
}
}
Related
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?
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
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);
}
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;
Where time and easing are the same, but with multiple properties:
#mixin transitionPrefixMultiple($time, $properties...) {
$transition: ();
#each $property in $properties {
$transition: append(
$transition, ($property $time cubic-bezier(.42, 0, .58, 1)), $separator: comma
);
}
-webkit-transition: $transition;
-moz-transition: $transition;
-ms-transition: $transition;
-o-transition: $transition;
transition: $transition;
}
Usage:
#include transitionPrefixMultiple(150ms, width, background-color, etc);
Thank you #nidhishs06 as this is a cleaner version of your answer
So, I've been messing around with creating a bit of code in CSS that is a list of animations set for one element. It's basically just a loop, but I need to be able to change the timing of each time it goes off. Basically, I'd like something as simple as this:
$intro-duration:1s;
$intro-delay:6.5s;
$intro-separation:0.7s;
$intro-style:ease;
#mixin intro($multiplier) {
-webkit-animation:intro $intro-duration $intro-separation*$multiplier+$intro-delay $intro-style;
}
.intro {
#include intro(-1);
#include intro(0);
#include intro(1);
#include intro(2);
#include intro(3);
}
But having that, it comes out like:
.intro {
-webkit-animation: intro 1s 5.8s ease;
-webkit-animation: intro 1s 6.5s ease;
-webkit-animation: intro 1s 7.2s ease;
-webkit-animation: intro 1s 7.9s ease;
-webkit-animation: intro 1s 8.6s ease;
}
Which would be all fine and dandy, but I obviously need to be able to leave off the "-webkit-animation" as well as the semi-colon in place of a commas, in order to properly combine the string of animation. So it needs to be this:
.intro {
-webkit-animation:
intro 1s 5.8s ease,
intro 1s 6.5s ease,
intro 1s 7.2s ease,
intro 1s 7.9s ease,
intro 1s 8.6s ease; }
I totally feel like I'm really just over complicating it and feel that if I were to simply step away from it for a few hours, I'd come up with the solution, but I've tried a few different things and am coming up short. Any help to simplify this code would be much appreciated!
EDIT: Removed a few lines of the repeating code to try and keep it simple.
You need to create a list:
#mixin intro($multiplier...) {
$collector: ();
#each $i in $multiplier {
$collector: append($collector, intro $intro-duration $intro-separation* $i+ $intro-delay $intro-style, comma);
}
animation: $collector;
}
.intro {
#include intro(-1, 0, 1, 2, 3);
}
Alternately:
#mixin intro($start, $end) {
$collector: ();
#for $i from $start through $end {
$collector: append($collector, intro $intro-duration $intro-separation* $i+ $intro-delay $intro-style, comma);
}
animation: $collector;
}
.intro {
#include intro(-1, 3);
}
And make sure you're providing all prefixes (as appropriate) + non-prefixed properties, not just webkit prefixes.
I use a #mixin to add different transition properties to elements. Let's say I have this in my .scss:
#mixin transition($prop, $sec){
-webkit-transition: $prop $sec;
-moz-transition: $prop $sec;
-ms-transition: $prop $sec;
-o-transition: $prop $sec;
transition: $prop $sec;
}
then I call:
.sample{
#include transition(background-color, 0.2s);
#include transition(margin, 0.3s)
}
.sample has only got margin transition, but I also want background-color transition: is there any simple way to get it working?
It's important that I have different calls
There is no way in SASS to concatenate properties and I don't know if exists a CSS external tool to do this task. Sass was created to improve CSS capabilities and not to allow programmers to develop bad programming practices. I don't really know the purpose of create multiple CSS declaration statements when you can keep them all in a single statement. Keeping all your transitions in one statement improves considerably your structure, your workflow and the performance of your Sass code.
Ok, that said, and as you have mentioned before "let the horrible kludge be".
Here are two different mixins for you one for shorthand transition declaration and another for the long form, differences between them in processing and even load time are negligible, the only noticeable difference is in the style of your code.
Long form mixin
#mixin transition($properties, $durations, $timing-function: null, $delay: null) {
$declarations: (property, $properties),
(duration, $durations),
(timing-function, $timing-function),
(delay, $delay);
#each $declaration in $declarations {
#if nth($declaration, 2) {
$output: ();
#each $val in nth($declaration, 2) {
$output: append($output, $val, comma);
}
#each $prefix in '-webkit-', '-moz-', '-ms-', '-o-', '' {
#{$prefix}transition-#{nth($declaration, 1)}: $output;
}
}
}
}
It's similar to #LeBen mixin but you can use the include with comma separated arguments without quotes:
#include transition(background-color margin, 0.2s 0.3s);
Shorthand form
#mixin transition($declarations...) {
#each $prefix in '-webkit-', '-moz-', '-ms-', '-o-', '' {
#{$prefix}transition: $declarations;
}
}
Here's the way to implement it in your code
#include transition(background-color 0.2s, margin 0.3s);
And now, to solve your problem with "different calls" the only way to deal with them, in my opinion, is using append() list function.
Let's go with the example. I'm going to use shorthand mixin form because it's easier to implement.
Imagine that you have four pages, three partials (_variables.scss, _page1.scss, _page2.scss, _page3.scss) and a style.scss file which imports the other:
_VARIABLES.SCSS
// Here comes the variable declaration
$transition-list: color 1s;
_PAGE1.SCSS
// Using append($list, $val, $separator:auto) list function
// we can add some items to $transition-list
$transition-list: append($transition-list, margin 2s, comma);
_PAGE2.SCSS
// You can add also the output of a function
#function example(){
#return unquote("background-color 1s")
}
$transition-list: append($transition-list, example(), comma);
STYLE.SCSS
// You can add new values into the same page
$transition-list: append($transition-list, padding 4s, comma);
$transition-list: append($transition-list, border 10s, comma);
// And finally you only need to use the include to generate the final transition
example {
#include transition($transition-list);
}
As I've said before, I don't recommend to use this method, it's not a good practice.
Your mixin is too rigid and don't feel like natural CSS. Personally, I recommend using the mixins provided by Compass, especially since it should handle prefixed values as well. If you just want a simple mixin, you want to use variable arguments like so:
#mixin transition($values...) {
-webkit-transition: $values;
// other prefixes
transition: $values;
}
#mixin transition-property($values...) {
-webkit-transition-property: $values;
// other prefixes
transition-property: $values;
}
#mixin transition-delay($values...) {
-webkit-transition-delay: $values;
// other prefixes
transition-delay: $values;
}
// etc
.foo {
#include transition(background-color, margin); // or transition-property
#include transition-delay(0.2s);
}
Output:
.foo {
-webkit-transition: background-color, margin;
transition: background-color, margin;
-webkit-transition-delay: 0.2s;
transition-delay: 0.2s;
}
Alternate Usage:
.foo {
#include transition(background-color 0.2s, margin 0.3s);
}
Output:
.foo {
-webkit-transition: background-color 0.2s, margin 0.3s;
transition: background-color 0.2s, margin 0.3s;
}
Here is the mixin you could use:
#mixin transition($properties, $durations, $timing-function: null, $delay: null) {
$props: unquote($properties);
$durs: unquote($durations);
-webkit-transition-property: $props;
-moz-transition-property: $props;
-ms-transition-property: $props;
-o-transition-property: $props;
transition-property: $props;
-webkit-transition-duration: $durs;
-moz-transition-duration: $durs;
-ms-transition-duration: $durs;
-o-transition-duration: $durs;
transition-duration: $durs;
#if ($timing-function) {
-webkit-transition-timing-function: $timing-function;
-moz-transition-timing-function: $timing-function;
-ms-transition-timing-function: $timing-function;
-o-transition-timing-function: $timing-function;
transition-timing-function: $timing-function;
}
#if ($delay) {
-webkit-transition-delay: $delay;
-moz-transition-delay: $delay;
-ms-transition-delay: $delay;
-o-transition-delay: $delay;
transition-delay: $delay;
}
}
With the following call
#include transition("background-color, margin", 0.2s);
I have 2 sass mixins that I would like to combine, 1 being for transitons and the other to handle vendor prefixes, so basically I want to transition the translateY value of an element so want to do something like the following:
#include transition( #include vendor(transform, .3s ease-in-out) );
Mixins
#mixin vendor($property, $value...){
-webkit-#{$property}:$value;
-moz-#{$property}:$value;
-ms-#{$property}:$value;
-o-#{$property}:$value;
#{$property}:$value;
}
#mixin transition($args...) {
-webkit-transition: $args;
-moz-transition: $args;
-ms-transition: $args;
transition: $args;
}
If anyone could advise how I actually do this or if there is a much better way that would be great. I don't need to use compass in case anyone suggests that.
With Compass
Compass is definitely the way to go about vendor prefixes. Then all you need to do is something like:
#import "compass";
test {
#include transition( transform 0.3s ease-in-out );
}
and the output will look like:
test {
-webkit-transition: -webkit-transform 0.3s ease-in-out;
-moz-transition: -moz-transform 0.3s ease-in-out;
-o-transition: -o-transform 0.3s ease-in-out;
transition: transform 0.3s ease-in-out;
}
DEMO
Own vendor mixins and functions (no Compass)
If for some reason you wouldn't use compass you can try making your vendor mixin a bit more exciting and add some functions (to check if an argument needs to be prefixed). Maybe something along these lines:
// loops through all arguments and prefixes the ones that need it (in this case only transform)
#function vendor-args($arg, $vendor) {
$result: ();
#each $i in $arg {
#if $i == transform { $result: append($result, #{$vendor}$i); }
#else { $result: append($result, $i); }
}
#return $result;
}
// general vendor mixin
#mixin vendor($property, $args...){
#each $vendor in ('-webkit-', '-moz-', '-ms-', '-o-', '') {
$out: null;
#each $arg in nth($args,1) {
$out: ($out, vendor-args($arg, $vendor));
}
#{$vendor}#{$property}: $out;
}
}
// general transition mixin
#mixin transition($args...) {
#include vendor(transition, $args);
}
// test
test {
#include transition( transform .3s ease-in-out, color .2s linear );
}
DEMO
Or if you want to check against a list of properties that need prefixing and not just transform, you can add another tiny function:
#function needs-vendor($p){
$l: transform, another-property-you-want-prefixed, and-another;
#each $i in $l {
#if $i == $p { #return terue; }
}
#return false;
}
and then use needs-vendor($i) instead of $i == transform.
Another thing is ... you don't really need to prefix transitions with -ms-. So you could make the vendor mixin take a list of prefixes as an optional argument, and use it like so:
#mixin transition($args...) {
#include vendor(transition, $args, ('-webkit-', '-moz-', '-o-', ''));
}
and voilá, here you go:
DEMO
But if you go with Compass it will do all the hard thinking for you ;-)
LESS allows parametric mixins, such as:
.transition(#property, #duration){
transition: #property #duration;
-moz-transition: #property #duration; /* Firefox 4 */
-webkit-transition: #property #duration; /* Safari and Chrome */
-o-transition: #property #duration; /* Opera */
}
However, this doesn't always work with properties such as transitions. If you are trying to have multiple transitions and attempt to call the mixin multiple times, the last mixin overrides all previously defined transitions. That's because the proper CSS3 syntax for defining multiple transitions is:
... {
transition: #property1 #duration1, #property2 #duration2, ...;
}
The only way that I can think of to define multiple transitions as mixins is to overload the mixin:
.transition(#property, #duration){...}
.transition(#property, #duration, #prop2, #dur2){...}
.transition(#property, #duration, #prop2, #dur2, #prop3, #dur3){...}
Is there a more robust and concise way of defining the transition mixin to take in a variable number of arguments and construct the appropriate transition CSS?
Context: Sometimes I'd like to transition on multiple properties; for example, a :hover might trigger transitions on background color, box-shadow, text-color, etc...
See my answer here: Multiple properties are getting treated as separate arguments in mixins
Summary: use this mixin for variable number of arguments:
.transition (#value1,#value2:X,...)
{
#value: ~`"#{arguments}".replace(/[\[\]]|\,\sX/g, '')`;
-webkit-transition: #value;
-moz-transition: #value;
-ms-transition: #value;
-o-transition: #value;
transition: #value;
}
UPDATE for LESS 1.3.3+
Output is the same, but note the difference in how the properties can be passed in the newer versions of LESS by using the semicolon instead of doing an escaped string:
#prop1: color;
#prop2: opacity;
#dur1: 3s;
#dur2: 4s;
.transition(#transString: 0) when not (#transString = 0) {
transition: #transString;
-moz-transition: #transString; /* Firefox 4 */
-webkit-transition: #transString; /* Safari and Chrome */
-o-transition: #transString; /* Opera */
}
.class1 {.transition();}
.class2 {.transition(width 2s, height 2s;);}
^
semicolon here
.class3 {.transition(#prop1 #dur1, #prop2 #dur2;);}
^
semicolon here
The semicolon forces the commas to be evaluated as list separators rather than parameter separators.
One Solution for LESS pre 1.3.3
We build the correct property arguments as a string for the transition, then use the escaped value (~) operator to translate that into the proprietary syntax needed. By using string interpolation (#{variableName}) we can even embed variables into the process, but the actual input needs to be in the form of an escaped string.
LESS Code
#prop1: color;
#prop2: opacity;
#dur1: 3s;
#dur2: 4s;
.transition(#transString: 0) when not (#transString = 0) {
transition: #transString;
-moz-transition: #transString; /* Firefox 4 */
-webkit-transition: #transString; /* Safari and Chrome */
-o-transition: #transString; /* Opera */
}
.class1 {.transition();}
.class2 {.transition(~" width 2s, height 2s");}
.class3 {.transition(~" #{prop1} #{dur1}, #{prop2} #{dur2}");}
CSS Output
Note: no .class1 is output because the guard expression insures that something is input (though it does not guard against improper input).
.class2 {
transition: width 2s, height 2s;
-moz-transition: width 2s, height 2s;
-webkit-transition: width 2s, height 2s;
-o-transition: width 2s, height 2s;
}
.class3 {
transition: color 3s, opacity 4s;
-moz-transition: color 3s, opacity 4s;
-webkit-transition: color 3s, opacity 4s;
-o-transition: color 3s, opacity 4s;
}
In LESS, you can separate arguments using commas OR semi-colons. For single values that include commas, you can terminate that single value with a semi-colon in order to send the list as a single value, like this:
.class {
.background-size(100%, auto;);
}
For multiple values, just use this syntax:
/* Example mixin */
.set-font-properties(#font-family, #size) {
font-family: #font-family;
font-size: #size;
}
/* Usage with comma-separated values */
.class {
.set-font-properties(Arial, sans-serif; 16px);
}
/* Output */
.class {
font-family: Arial, sans-serif;
font-size: 16px;
}
Easy peasy!
Note: This answer is not added with the intention of saying the existing answers are incorrect or obsolete. All the answers are valid and would still work. This one just provides a different method which in my opinion is a bit more complex but also more flexible in terms of how each argument can be mentioned as key-value pairs.
Advantages of using this method: This method would become more useful when there is a need to perform any extra operation on the values (say like adding unit as deg, px or performing any extra math operations etc) or dynamically adding the vendor prefixes for the #property also. For example there are times when you might want to pass only transform as an input property to the mixin but want to add -webkit-transform for the -webkit-transition and -moz-transform for the -moz-transition etc.
In this method, we make use of the ... feature which allows us to pass variable number of arguments to a mixin, loop over each argument that is passed, extract the name of the property along with the additional parameters (like duration, degree of rotation etc) and then use the merge feature that is provided by Less to concatenate the values specified for the property.
The +: concatenates the property values with a comma and was introduced in Less v1.5.0
The +_: concatenates the property values with a space and was introduced in Less v1.7.0.
.transition(#args...){
.loop-args(#argCount) when (#argCount > 0) {
.loop-args(#argCount - 1);
#arg: extract(#args, #argCount);
#property: extract(#arg,1);
#duration: extract(#arg,2);
-webkit-transition+: #property #duration;
-moz-transition+: #property #duration;
-o-transition+: #property #duration;
transition+: #property #duration;
}
.loop-args(length(#args));
}
div{
.transition(background, 1s; border-color, 2s; color, 2s);
}
.transform(#args...){
.loop-args(#argCount) when (#argCount > 0) {
.loop-args(#argCount - 1);
#arg: extract(#args, #argCount);
#property: extract(#arg,1);
#param: extract(#arg,2);
-webkit-transform+_: ~"#{property}(#{param})";
-moz-transform+_: ~"#{property}(#{param})";
-o-transform+_: ~"#{property}(#{param})";
transform+_: ~"#{property}(#{param})";
}
.loop-args(length(#args));
}
div#div2{
.transform(rotate, 20deg; scale, 1.5; translateX, 10px);
}
The above code when compiled would produce the below output:
div {
-webkit-transition: background 1s, border-color 2s, color 2s;
-moz-transition: background 1s, border-color 2s, color 2s;
-o-transition: background 1s, border-color 2s, color 2s;
transition: background 1s, border-color 2s, color 2s;
}
div#div2 {
-webkit-transform: rotate(20deg) scale(1.5) translateX(10px);
-moz-transform: rotate(20deg) scale(1.5) translateX(10px);
-o-transform: rotate(20deg) scale(1.5) translateX(10px);
transform: rotate(20deg) scale(1.5) translateX(10px);
}
Related Answer:
Here is an answer from seven-phases-max which explains more on how this method could be used to auto add vendor prefixes like I have mentioned in the advantages paragraph.
This should work, I think:
.transition(...) {
transition: #arguments;
-moz-transition: #arguments; /* Firefox 4 */
-webkit-transition: #arguments; /* Safari and Chrome */
-o-transition: #arguments; /* Opera */
}
... - is a valid less syntax, not something to be replaced.
Current as of LESS 1.4, the documentation (http://lesscss.org/features/#mixins-parametric-feature-mixins-with-multiple-parameters) suggests the proper way to handle this:
Using comma as mixin separator makes it impossible to create comma
separated lists as an argument. On the other hand, if the compiler
sees at least one semicolon inside mixin call or declaration, it
assumes that arguments are separated by semicolons and all commas
belong to css lists:
Concretely, mixin:
.transition(#prop-or-props) {
-webkit-transition: #prop-or-props;
-moz-transition: #prop-or-props;
-o-transition: #prop-or-props;
transition: #prop-or-props;
}
usage:
.transition(opacity .2s, transform .3s, -webkit-transform .3s;);
Note that multiple properties are separated by commas and the trailing semi-colon causes the comma separated list to be treated as a single parameter in the mixin.
It would be nicer to define the mixin with a rest... parameter and be able to extract each element of the arbitrary-length arguments for separate handling, but the use-case I'm thinking of is adding vendor prefixes to transform transitions (so i could call it simply with .transition(opacity .2s, transform .3s) and have the -webkit-transform bit added automatically) and perhaps this is better handled by a different utility anyway (gulp-autoprefixer, for example).