11

I want to create the following in a stylesheet using SASS:

.dC1, .dC2, .dC3 {
    color: white;
}
.dC4, .dC5 {
    color: black;
}

using a @while loop in SASS such as the following (I know it's a bit off, I will refine it once I figure out how to set it up):

$i: 1;
$whiteLevel: 3;
$blackLevel: 5;
$val: nil;

@while $i <= $whiteLevel {
    $val: $val + .dC#{$i};
    $i: $i + 1;
}

$val {
    color: white;
}

$val: nil;

@while $i > $whiteLevel and $i <= $blackLevel {
    $val: $val + .dC#{$i};
    $i: $i + 1;
}

$val {
    color: black;
}

Yes, I know it's ugly as sin but I think it gets across what I want. Ultimately the $whiteLevel and $blackLevel (or whateever I end up calling them) will be in a _base.scss file so I can change the different levels and number of classes "on the fly."

Is it possible to do it and can someone point me in the right direction?

Thanks in advance and looking forward to hearing any suggestions!

Edit: To clarify I can use the following code to get the same result:

$whiteLevel: 3;

.cW {
    color: white;
}

.cB {
    color: black;
}

@for $i from 1 through 5{
    .dC#{$i} {
        @if $i <= $whiteLevel {
            @extend .cW;
        } @else {
            @extend .cB;
        }
    }
}

This produces:

.cW, .dC1, .dC2, .dC3 {
    color: white;
}

.cB, .dC4, .dC5 {
    color: black;
}

Which is the 99% solution, but it means I have to have a specific class already built to accomodate the @extend. My goal is to make this totally dynamic and dependent on the values of $whiteLevel and $blackLevel. If I set them to 0 I want to make it so no class is created.

Hope that helps clarify a bit.

Edit edit!

Thanks to cimmanon here is the solution I will using (based on provided solution, gotta love that % sign):

$whiteLevel: 3;

%cW {
    color: white;
}

%cB {
    color: black;
}

@for $i from 1 through 5{
    .dC#{$i} {
        @if $i <= $whiteLevel {
            @extend %cW;
        } @else {
            @extend %cB;
        }
    }
}

Many thanks cimmanon!

anjiTechGuy
  • 125
  • 2
  • 7
  • Did you try running this code? Was there an error (what was the error?)? Was the output incorrect? – cimmanon May 11 '13 at 11:49
  • Throws the following error: Syntax error: Invalid CSS after " $val: $val + ": expected expression (e.g. 1px, bold), was ".dC#{$i};" – anjiTechGuy May 11 '13 at 12:10

1 Answers1

15

To correctly write that expression would be like this:

$val: $val + '.dC#{$i}';

But you're forgetting to account for the comma, so your selector ends up looking like this:

.dC4.dC5 {
  color: black;
}

Even if you did add the comma, you'd end up with all 3 classes preceded by a comma. There are more efficient ways to do what you're looking for that properly account for commas:

$minLevel: 1;
$whiteLevel: 3;
$blackLevel: 5;

%white {
    color: white;
}

@for $i from $minLevel through $whiteLevel {
    .dC#{$i} {
        @extend %white;
    }
}

$blackSelectors: ();
@for $i from $whiteLevel + 1 through $blackLevel {
    $blackSelectors: append($blackSelectors, unquote('.dC#{$i}'), comma);
}

#{$blackSelectors} {
    color: black;
}

Output:

.dC1, .dC2, .dC3 {
  color: white;
}

.dC4, .dC5 {
  color: black;
}
cimmanon
  • 67,211
  • 17
  • 165
  • 171
  • We posted at the same time and after reviewing your answer, all I was missing out on was the % instead of . for the selector. Thanks! – anjiTechGuy May 11 '13 at 12:44