Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merge string and variable to a variable with SASS [duplicate]

Tags:

variables

sass

I want to merge a variable and a string to a new variable, like the following:

$product_bodyclass_list: class1 class2 class3 class4;

$product_class1_color: #C00;
$product_class2_color: #00C;
$product_class3_color: #0C0;
$product_class4_color: #000;

@each $bodyclass in $product_bodyclass_list {
    .page-#{$bodyclass} {
        a {
            color: $product_#{$bodyclass}_color; // This is wrong
        }
    }
}

Does anybody know how to do this?

like image 877
sneeky Avatar asked Apr 03 '13 13:04

sneeky


People also ask

How do you combine variables and strings?

In JavaScript, we can assign strings to a variable and use concatenation to combine the variable to another string. To concatenate a string, you add a plus sign+ between the strings or string variables you want to connect.

How do I concatenate strings in sass?

Strings can be concatenated (linked together) using the + operator. If you mix quoted and unquoted strings when concatenating, the result will be whichever is on the left side of the operator.


2 Answers

No, you can't have dynamic variables.

From the docs:

You can also use SassScript variables in selectors and property names using #{} interpolation

You can accomplish the same effect using two lists and the nth() function.

$products: class1, class2, class3, class4;    
$product_colors: #C00, #00C, #0C0, #000;

$i: 1;
@each $class in $products {
    .page-#{$class} {
        a {
            color: nth($product_colors, $i)
        }
    }
  $i: $i + 1;
}

Also, it might be cleaner to use the @for directive:

@for $i from 1 through length($products) {
    .page-#{nth($products, $i)} {
        a {
            color: nth($product_colors, $i)
        }
    }
}

In addition, if you want to define the variables explicitly so you can use them elsewhere, make a list of variables:

$product_class1_color: #C00;
$product_class2_color: #00C;
$product_class3_color: #0C0;
$product_class4_color: #000;

$product_colors: $product_class1_color, $product_class2_color, $product_class3_color, $product_class4_color;
like image 111
bookcasey Avatar answered Sep 22 '22 18:09

bookcasey


UPDATE: Sass maps make this answer pretty much obsolete.

Another option is to use one list, with two elements each, and use it as a hashmap.

$products: class1 #C00, class2 #00C, class3 #0C0, class4 #000;

@each $kvp in $products { // kvp stands for 'key-value pair'
    .page-#{nth($kvp, 1)} {
        a {
            color: nth($kvp, 2);
        }
    }
}

I like to make simple functions to make the meaning of my code clearer. I'd probably do something more like:

@function kvp-key($kvp) {
    @return nth($kvp, 1);
}

@function kvp-value($kvp) {
    @if length($kvp) == 2 {
        @return nth($kvp, 2);
    } @else {
        @warn "argument was not a key-value pair";
        @return null;
    }
}

And then I'd reimplement the loop like this:

@each $kvp in $products { // kvp stands for 'key-value pair'
    .page-#{kvp-key($kvp)} {
        a {
            color: kvp-value($kvp);
        }
    }
}

We haven't saved any lines, but we've made the intent of the loop a bit clearer.

like image 33
Paul d'Aoust Avatar answered Sep 21 '22 18:09

Paul d'Aoust