7

I'm working on converting Unsemantic from SASS to LESS and while I'm building the loop to create my classes:

    .populateGridClasses (@index, @interval) when (@index > 0) {
    @num: @index * @interval;
    (~".eh-grid-@{num}, .eh-mobile-grid-@{num}, .eh-tablet-grid-@{num}") {
        .grid();
    }
   .populateGridClasses(@index - 1, @interval);
}
.populateGridClasses (0, @interval) {}

// Create the grids in an inverval of 5
.populateGridClasses(20, 5);

// Create the grids in thirds .populateGridClasses(3, 33);

It creates the classes as so:

.eh-grid-100, .eh-mobile-grid-100, .eh-tablet-grid-100 {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  padding: 0 10px;
}
.eh-grid-95, .eh-mobile-grid-95, .eh-tablet-grid-95 {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  padding: 0 10px;
}
...

Obviously, that could be condesnsed so that all 6 of those classes are defined at once. So my idea is to use the loop to create a giant string that I'll then add the .grid() mixin to:

@test: "";
.populateGridClasses4 (@index, @interval) when (@index > 0) {
    @num: @index * @interval;
    @ntest: ".eh-grid-@{num}, .eh-mobile-grid-@{num}, .eh-tablet-grid-@{num}";
    @test: "@{test}@{ntest}";
.populateGridClasses4(@index - 1, @interval);
}
.populateGridClasses4 (0, @interval) {}
.populateGridClasses4(20, 5);

("@{test}"){
    padding-left: 1px;
}

But that gives me a LESS error LESS: Out of stack space. Any idea on how I can create this massive string so I can create 69 classes and only define them once? Programmatically, of course.

1 Answer 1

7

You could try passing another attribute to the mixin ... like this, where I added to your code the @t1 to the arguments and define the @t2 in the loop, and pass it on. Now you'll be writing to a variable only in the scope of one loop step, and not trying to overwrite the same variable over again in the recursion (does not agree with less). So this is your code, that should not get the error you mention anymore:

    @test: "";

    .populateGridClasses4 (@index, @interval, @t1) when (@index > 0) {
        @num: @index * @interval;
        @ntest: ".eh-grid-@{num}, .eh-mobile-grid-@{num}, .eh-tablet-grid-@{num}";
        @t2: ~"@{t1}@{ntest}";
    .populateGridClasses4(@index - 1, @interval,@t2);
    }

    .populateGridClasses4 (0, @interval,@t1) {}

    .populateGridClasses4(20, 5, @test);

    @{t2} {
        padding-left: 1px;
    }

Also you need use ~ for class interpolation, not to return the class names between quotation marks.

Edit: The above will only work in 1.3.3, but for your approach to work in 1.4 you need to tweak it a little. Also I noticed that the way you were joining the strings did not add commas between class names of each loop, so I added another step here, this should now do the right thing in1.4 and previous versions of LESS.

    .populateGridClasses4(1,@num,@t1) {
        @test: ~"@{t1}, .eh-grid-@{num}, .eh-mobile-grid-@{num}, .eh-tablet-grid-@{num}";
    }

    .populateGridClasses4(@index, @interval, @t1) when (@index > 1) {
        @num: (@index * @interval);
        @t2: "@{t1}, .eh-grid-@{num}, .eh-mobile-grid-@{num}, .eh-tablet-grid-@{num}";
        .populateGridClasses4((@index - 1),@interval,@t2);
    }

    .populateGridClasses4(@index,@interval) {
        @num: (@index * @interval);
        @t2: ".eh-grid-@{num}, .eh-mobile-grid-@{num}, .eh-tablet-grid-@{num}";
       .populateGridClasses4((@index - 1), @interval, @t2);
    }

    .populateGridClasses4(20, 5);
    @{test} { padding-left: 1px; }

the output CSS is:

  .eh-grid-100, .eh-mobile-grid-100, .eh-tablet-grid-100, .eh-grid-95, .eh-mobile-grid-95, .eh-tablet-grid-95, .eh-grid-90, .eh-mobile-grid-90, .eh-tablet-grid-90, .eh-grid-85, .eh-mobile-grid-85, .eh-tablet-grid-85, .eh-grid-80, .eh-mobile-grid-80, .eh-tablet-grid-80, .eh-grid-75, .eh-mobile-grid-75, .eh-tablet-grid-75, .eh-grid-70, .eh-mobile-grid-70, .eh-tablet-grid-70, .eh-grid-65, .eh-mobile-grid-65, .eh-tablet-grid-65, .eh-grid-60, .eh-mobile-grid-60, .eh-tablet-grid-60, .eh-grid-55, .eh-mobile-grid-55, .eh-tablet-grid-55, .eh-grid-50, .eh-mobile-grid-50, .eh-tablet-grid-50, .eh-grid-45, .eh-mobile-grid-45, .eh-tablet-grid-45, .eh-grid-40, .eh-mobile-grid-40, .eh-tablet-grid-40, .eh-grid-35, .eh-mobile-grid-35, .eh-tablet-grid-35, .eh-grid-30, .eh-mobile-grid-30, .eh-tablet-grid-30, .eh-grid-25, .eh-mobile-grid-25, .eh-tablet-grid-25, .eh-grid-20, .eh-mobile-grid-20, .eh-tablet-grid-20, .eh-grid-15, .eh-mobile-grid-15, .eh-tablet-grid-15, .eh-grid-10, .eh-mobile-grid-10, .eh-tablet-grid-10, .eh-grid-5, .eh-mobile-grid-5, .eh-tablet-grid-5 {
    padding-left: 1px;
  }
Sign up to request clarification or add additional context in comments.

2 Comments

Wow, this is simply stunning. I'm very, very impressed. I have one more question if you don't mind. Instead of defining @test, is there a way we can pass a string as a parameter and have that first function (our 1 condition) create a variable named after the string content of what we pass in? Ex: .populate-grid-classes(20, 5, "classes");. I'm strugging on it. I'd like to move this functionality out into my mixins LESS file and also would like to re-use this code for 33% and 66%, so my idea would be to make your last line ` @{test1}, @{test2} { padding-left: 1px; }` as an example.
Also if you know how I could use linebreaks with these strings, Google is on a "let's ignore 'LESS CSS'" kick...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.