简体   繁体   中英

SASS Mixin with optional and variable parameters

Is there a way to use both optional and variable elements in a sass mixin?

i try

@mixin name($className,  $centered: false, $dimension...)

but the first dimension value is assigned to $centered

switching parameters order don't compile

@mixin name($className, $dimension..., $centered: false )

the error is:

SASSInvalid CSS after "..., $dimension...": expected ")", was ", $centered: fa..."

since the mixin without the optional parameter is used in many place (over 70) i dont want yo change it all to add the new parameters, so i want to leave it optional?

Any way to change this mixin or i have to leave the original without $centered and create an ovverride with the new parameter?

for info this is the mixin body:

    @for $i from 1 through length($dimension){                              
        @if($centered) {
            .#{$className}Td#{$i}, .#{$className}Th#{$i}  { 
                width: nth($dimension, $i); 
                text-align:center;
            }
        }
        @else{
            .#{$className}Td#{$i}, .#{$className}Th#{$i} {width: nth($dimension, $i); }
        }
    }

EDIT with complete cowking example:

simply iam defining css for column width of my table in a faster way, so this

@include nome("columnsName", 40%, 30%, 30%);

is rendered in that way:

.columnsNameTd1, .columnsNameTh1{width: 40%;}

.columnsNameTd2, .columnsNameTh2{ width: 30%; }

.columnsNameTd3, .columnsNameTh3{ width: 30%;}

i want a way to text-align center all my columns, maybe can be interesting see if there is a way do to specify what column to center, making all other left by default

You can't do what you're asking because variable arguments (the ... syntax) absolutely must be last . You have 2 options, I recommend option #2.

Option 1 (examine the last element to see if it is a boolean):

@mixin name($className, $dimension...) {
    $last: nth($dimension, length($dimension));
    $centered: if(type-of($last) == bool, $last, false);
    $length: if(type-of($last) == bool, length($dimension) - 1, length($dimension));

    @for $i from 1 through $length {
        .#{$className}Td#{$i}, .#{$className}Th#{$i} {
            width: nth($dimension, $i);
            @if($centered) {
                text-align: center;
            }
        }
    }
}

Option 2 (use the @content directive):

@mixin name($className, $dimension...) {
    @for $i from 1 through length($dimension) {
        .#{$className}Td#{$i}, .#{$className}Th#{$i} {
            width: nth($dimension, $i);
            @content;
        }
    }
}

// usage
@include name(rar, 10%, 20%, 30%);

@include name(rar, 10%, 20%, 30%) {
    text-align: center;
}

ok, what if you try testing the last value of your list, since it seems that sass does not support anything else after a list as a parameter.

@function last($list) {
  @return nth($list, length($list));
}
//returns the last item of a list

@mixin nome($className, $dimension...) {
    @for $i from 1 through length($dimension){
        @if(last($dimension) == true) {
            .#{$className}Td#{$i}, .#{$className}Th#{$i}  {
                width: nth($dimension, $i);
                text-align:center;
            }
        }
        @else{
            .#{$className}Td#{$i}, .#{$className}Th#{$i} {width: nth($dimension, $i); }
        }
    }
}

so if you add @include nome("className", 4%, 4%, 4%, 6%, 70%, 12%, true); and the last value is true it should center your div, or whatever you trying to do!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM