How to dynamically generate a list of classes with commas separating them?
Asked Answered
K

3

91

I'm working with the SCSS syntax of SASS to create a dynamic grid system but I've hit a snag.

I'm trying to make the grid system completely dynamic like this:

$columns: 12;

then I create the columns like this:

@mixin col-x {
  @for $i from 1 through $columns {
  .col-#{$i} { width: $column-size * $i; }
  }
}

Which outputs:

.col-1 {
    width: 4.16667%;
  }

.col-2 {
    width: 8.33333%;
}
etc...

This works well but what I want to do next is dynamically generate a long list of column classes separated by commas based on the number of $columns chosen - e.g I want it to look like this:

.col-1,
.col-2,
.col-3,
.col-4,
 etc... {
float: left;
}

I've tired this:

@mixin col-x-list {
  @for $i from 1 through $columns - 1 {
  .col-#{$i}-m { float: left; }
  }
}

but the output is this:

.col-1 {
  float: left;
}
.col-2 {
  float: left;
}
etc...

I'm a little stuck on the logic here as well as the SCSS syntax required to create something like this.

Does anyone have any ideas?

Kerrykersey answered 30/9, 2013 at 6:35 Comment(2)
Out of curiosity: "@mixin col-x { @for $i from 1 through $columns { .col-#{$i} { width: $column-size * $i; } } }" can you explain what this code do exactly?Infusible
@Infusible It loops through the number of columns I set e.g. $columns: 6; and creates a class called col-1, col-2 etc. So if I want 6 columns it only cycles up to col-6. It then gives each col- a width of (100% divided by number of $columns then multiplied by it's column number) e.g. col-3 = (100% / 6) * 3 = 50%.Kerrykersey
F
134

I think you may want to take a look at @extend. If you set that up something like:

$columns: 12;

%float-styles {
  float: left;
}

@mixin col-x-list {
  @for $i from 1 through $columns {
      .col-#{$i}-m { @extend %float-styles; }
  }
}

@include col-x-list;

It should render in your css file as:

.col-1-m, .col-2-m, .col-3-m, .col-4-m, .col-5-m, .col-6-m, .col-7-m, .col-8-m, .col-9-m, .col-10-m, .col-11-m, .col-12-m {
  float: left;
}

@extend in the docs.

Flinders answered 30/9, 2013 at 7:12 Comment(1)
Great. Your answer also describes how to create custom code like .col-#{$i}-m.Adinaadine
C
29

There's also a way to do what your question is specifically asking for: generate (and use) a list of classes with commas separating them. D.Alexander's response totally works in your situation, but I'm posting this alternative in case there's another use case for someone looking at this question.

Here's a Pen demonstrating: http://codepen.io/davidtheclark/pen/cvrxq

Basically, you can use Sass functions to achieve what you want. Specifically, I'm using append to add classes to my list, separated by commas, and unquote to avoid compilation conflicts with the period in the classnames.

So my mixin ends up looking like this:

@mixin col-x {
  $col-list: null;
  @for $i from 1 through $columns {
    .col-#{$i} {
      width: $column-size * $i;
    }
   $col-list: append($col-list, unquote(".col-#{$i}"), comma);
  }
  #{$col-list} {
    float: left;
  }
}
Cancan answered 3/10, 2013 at 14:15 Comment(0)
H
13

thnx to @davidtheclark here is a more generic version:

@mixin attr-x($attr, $attr-count: 10, $attr-steps: 10, $unit: '%') {
    $attr-list: null;
    @for $i from 1 through $attr-count {
        $attr-value: $attr-steps * $i;

        .#{$attr}#{$attr-value} {
            #{$attr}: #{$attr-value}#{$unit};
        }

        $attr-list: append($attr-list, unquote(".#{$attr}-#{$attr-value}"), comma);
    }

    #{$attr-list} {
        //append style to all classes
    }
}

Use it like this:

@include attr-x('margin-left', 6, 5, 'px');
//or
@include attr-x('width');

The result looks like this:

.margin-left5 {
  margin-left: 5px; }

.margin-left10 {
  margin-left: 10px; }

...

.margin-left30 {
  margin-left: 30px; }

//or

.width10 {
  width: 10%; }

.width20 {
  width: 20%; }

...

.width100 {
  width: 100%; }
Herron answered 6/6, 2017 at 10:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.