Search code examples
loopsstylus

Generating selectors with Stylus loop


In Stylus, I am trying to generate :nth-of-type() selectors based on a color array. This is actually my first time with arrays in stylus so I am a bit perplexed as per the semicolon- and bracket-free syntax I am seeing in examples.

The goal is to have an equivalent of the following:

.chart {
  li {
    display: flex;
    align-items: flex-end;

    &:nth-of-type(1) {
      background-color: #FFE3A9;
      span {
        background-color: #FFCC66;
      }
    }
    &:nth-of-type(2) {
      background-color: #FCCCA2;
      span {
        background-color: #F79850;
      }
    }
  }
}

My attempt:

bg_colors = (#FFEDA9 #FDCCA2)
fill_colors = (#FFCD66 #FD9850)

.chart {
  li {
    display: flex;
    align-items: flex-end;

    for num in range(0, 1)
      &:nth-of-type({num})
        background-color: bg_colors[num]
        span
          background-color: fill_colors[num]
  }
}

I am getting compilation errors from an unexpected } (angular cli) so I am wondering where my syntax is wrong.


Solution

  • OK. So, this question is unique to the duplicate I mentioned - mainly because there are 2 arrays used in the loop. You may want to rename the question for future searches.

    First off, it took me a long time to realise I needed to take error messages seriously. In your case - it's telling you there are brackets - and there shouldn't be - so they are unexpected. Remove them. Stylus syntax is mostly just like SCSS - all you have to do is type less things - and ensure that your indents are perfect. The indents replace the brackets in clarifying the rules' beginning and end. Remove ALL brackets - and semicolons. *(Side note - use $var for variables / they are likely to be required later - also - : used to be an option - they are also going to be required)

    Second, I'm guessing that this for loop is like an each loop in Javascript, so you can get currentvalue, currentIndex, fullArray parameters out with a comma separated list. (I'm not 100% on that)

    for fillColor, currentIndex in $fillColorArray

    This would allow you to access the color and its index as these placeholders.

    Here is alive example: https://codepen.io/sheriffderek/pen/64c6791116c3a180cb196610f9962f17/ - you can choose to view the compiled CSS in the stylus pane's little arrow icon.


    markup

    <ul class="chart-list one">
        <li class="chart">
            <span>Chart 1</span>
        </li>
        <li class="chart">
            <span>Chart 2</span>
        </li>
        <li class="chart">
            <span>Chart 3</span>
        </li>
        <li class="chart">
            <span>Chart 4</span>
        </li>
    </ul>
    
    ...
    

    You can do this a few ways - depending on the application. Here is an example with 2 loops - and another with a single loop.


    stylus

    $fillColorArray = (#f06 pink)
    $textColorArray = (white #f06)
    
    remove-list-styles()
        list-style: none
        margin: 0
        padding: 0
    
    .chart-list
        remove-list-styles()
        margin-bottom: 2rem
        background: lightgray
        .chart
            padding: 1rem
    
    .chart-list.one
        //
        .chart
            //
            for fillColor, currentIndex in $fillColorArray
                &:nth-of-type({currentIndex + 1})
                    background: fillColor
            for textColor, currentIndex in $textColorArray
                &:nth-of-type({currentIndex + 1})
                    span
                        color: textColor
    
    .chart-list.two
        //
        .chart
            //
            for fillColor, currentIndex in $fillColorArray
                &:nth-of-type({currentIndex + 1})
                    background: fillColor
                    span
                        color: $textColorArray[currentIndex]
    
    // &:nth-of-type( 2n + {currentIndex + 1})
    // if you want it to repeat at those intervals
    .chart-list.three
        //
        .chart
            //
            for fillColor, currentIndex in $fillColorArray
                &:nth-of-type( 2n + {currentIndex + 1})
                    background: fillColor
                    span
                        color: $textColorArray[currentIndex]