36

I've got a bunch of elements: (#cp1, #cp2, #cp3, #cp4)

that I want to add a background colour to using SCSS.

My code is:

$colour1: rgb(255,255,255); // white
$colour2: rgb(255,0,0); // red
$colour3: rgb(135,206,250); // sky blue
$colour4: rgb(255,255,0);   // yellow

@for $i from 1 through 4 {
    #cp#{i} {
        background-color: rgba($(colour#{i}), 0.6);

        &:hover {
            background-color: rgba($(colour#{i}), 1);
            cursor: pointer;
        }
    }
}
tobyn
  • 460
  • 1
  • 5
  • 6

3 Answers3

60

Instead of generating the variables names using interpolation you can create a list and use the nth method to get the values. For the interpolation to work the syntax should be #{$i}, as mentioned by hopper.

$colour1: rgb(255,255,255); // white
$colour2: rgb(255,0,0); // red
$colour3: rgb(135,206,250); // sky blue
$colour4: rgb(255,255,0);   // yellow

$colors: $colour1, $colour2, $colour3, $colour4;

@for $i from 1 through length($colors) {
    #cp#{$i} {
        background-color: rgba(nth($colors, $i), 0.6);

        &:hover {
            background-color: rgba(nth($colors, $i), 1);
            cursor: pointer;
        }
    }
}
Xabriel
  • 709
  • 4
  • 4
38

As @hopper has said the main problem is that you haven't prefixed interpolated variables with a dollar sign so his answer should be marked as the correct, but I want to add a tip.

Use @each rule instead of @for loop for this specific case. The reasons:

  • You don't need to know the length of the list
  • You don't need to use length() function to calculate the length of the list
  • You don't need to use nth() function
  • @each rule is more semantic than @for directive

The code:

$colours: rgb(255,255,255), // white
          rgb(255,0,0),     // red
          rgb(135,206,250), // sky blue
          rgb(255,255,0);   // yellow

@each $colour in $colours {
    #cp#{$colour} {
        background-color: rgba($colour, 0.6);

        &:hover {
            background-color: rgba($colour, 1);
            cursor: pointer;
        }
    }
}

Or if you prefer you can include each $colour in the @each directive instead of declare $colors variable:

$colour1: rgb(255,255,255); // white
$colour2: rgb(255,0,0);     // red
$colour3: rgb(135,206,250); // sky blue
$colour4: rgb(255,255,0);   // yellow

@each $colour in $colour1, $colour2, $colour3, $colour4 {
    #cp#{$colour} {
        background-color: rgba($colour, 0.6);

        &:hover {
            background-color: rgba($colour, 1);
            cursor: pointer;
        }
    }
}

Sass Reference for @each directive

Alex Guerrero
  • 2,109
  • 1
  • 19
  • 28
19

SASS variables still need to be prefixed with a dollar sign inside interpolations, so every place you have #{i}, it should really be #{$i}. You can see other examples in the SASS reference on interpolations.

hopper
  • 13,060
  • 7
  • 49
  • 53