Question

Instead of doing something like this (which is obviously inefficient):

@mixin padding($top, $right, $bottom, $left) {

    $top: $top * $spacer;
    $right: $right * $spacer;
    $bottom: $bottom * $spacer;
    $left: $left * $spacer;

    $output: $top $right $bottom $left;

    padding: $output;

}

Can I do something similar to this?

@mixin padding($top:"", $right:"", $bottom:"", $left:"") {

    $params: $top, $right, $bottom, $left;
    $output: "";

    @each $var in $params {
        $var: $var * $spacer;
        $output: $output + $var;
    }

    padding: $output;

}
Was it helpful?

Solution

Yes you can =)

In this case you can also skip the first step and use $params... as the parameter (variable argument list), and then you can have padding with 1, 2, 3, or 4 values.

@mixin padding($params...) {
    $output: ();
    @each $var in $params {
        $var: $var * $spacer;
        $output: join( $output, $var );
    }
    padding: $output;
}

If you use the join function instead of string concatenation you won't have troubles separating the values with spaces when printing out (a list gets automatically compiled to CSS as space separated elements).

DEMO


And if you want to make sure to limit the params to 4 max, you can do something like this instead of the @each loop:

$n: length($params);
@for $i from 1 through if( $n < 4, $n , 4) {
    $var: nth($params,$i) * $spacer;
    $output: join( $output, $var );
}

DEMO


However, if you want to stick with strings and concatenation instead of lists, you would need to use an additional space in the concatenation inside the loop (e.g. $output + " " + $var) and then return the $output with string interpolation #{$output} or using unquote($output). But you would end up with an extra space attached to the string ... and would need to apply some additional logic in case you would want to get rid of it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top