Search code examples
csslessweb-frontend

Less recursive mixin function not working correctly


So I wrote this recursive mixin with Less where I spin the color 30 degrees each time for 12 cycles (12*30 = 360). For some reason, however, some of my h1 tags are styled with exactly the same color.

#slab9 {
    .slabBG-color(#fff, 880px);
    .container {
        width:400px;
        @original:#95e858;
        float:left;
        margin:20px 40px;

        .color(@index, @color, @degrees:0) when (@index > 0) {
            @sColor:spin(@color, @degrees);
            .color-@{index} {   
                color:@sColor;
                span {
                    color:darken(@sColor, 10%);
                }
            }
            .color(@index - 1, @sColor, @degrees + 30);
        }
        .color(12, #95e858);

 (...)

    <section id="slab9">
      <div class="container">
        <h1 class="color-12">REST &<br /><span class="large">RELAX</span></h1>
      </div>
      <div class="container">
        <h1 class="color-11">REST &<br /><span class="large">RELAX</span></h1>
      </div>
      <div class="container">
        <h1 class="color-10">REST &<br /><span class="large">RELAX</span></h1>
      </div>
      <div class="container">
        <h1 class="color-9">REST &<br /><span class="large">RELAX</span></h1>
      </div>
      <div class="container">
        <h1 class="color-8">REST &<br /><span class="large">RELAX</span></h1>
      </div>
      <div class="container">
        <h1 class="color-7">REST &<br /><span class="large">RELAX</span></h1>
      </div>
      <div class="container">
        <h1 class="color-6">REST &<br /><span class="large">RELAX</span></h1>
      </div>
      <div class="container">
        <h1 class="color-5">REST &<br /><span class="large">RELAX</span></h1>
      </div>
      <div class="container">
        <h1 class="color-4">REST &<br /><span class="large">RELAX</span></h1>
      </div>
      <div class="container">
        <h1 class="color-3">REST &<br /><span class="large">RELAX</span></h1>
      </div>
      <div class="container">
        <h1 class="color-2">REST &<br /><span class="large">RELAX</span></h1>
      </div>
      <div class="container">
        <h1 class="color-1">REST &<br /><span class="large">RELAX</span></h1>
      </div>
    </section>

I know that similar recursive mixins escape the class name like: ~(".color-@{index}") {
but this produces an error altogether and outputs nothing.

Any help would be greatly appreciated. I've been looking at this forever


Solution

  • The problem is that you are not spinning the same color in every iteration. I reduced your mixin to the essential code below so you can see the problem:

    .container {
    
      .color(@index, @color, @degrees:0) when (@index > 0) {
        @sColor: spin(@color, @degrees); // here you spin 30 degrees
    
        .color-@{index} {
          color: @sColor;
          content: @degrees;
        }
        // here you call the mixin again with the spinned color and + 30 degrees!
        .color(@index - 1, @sColor, @degrees + 30); 
    
      }
    
      .color(12, #ff0000);
    }
    

    You are spinning the color +30 degrees, and calling the mixin again with that spinned color. That means you are not just incrementing steps of 30 degrees as it seems, but multiples of 30 (+30, +60, +90, +120) so you will eventually have spinned over 360 degrees several times before you finish. That's why you get repeated colors.

    If you wish 30 degree steps which will avoid repeating colors, call the mixin with the unspinned color:

    .container {
    
      .color(@index, @color, @degrees:0) when (@index > 0) {
        @sColor: spin(@color, @degrees);
    
        .color-@{index} {
          color: @sColor;
          content: @degrees;
        }
    
        .color(@index - 1, @color, @degrees + 30);
    
      }
    
      .color(12, #ff0000);
    }