Function to dynamically create classes from lists

2019-01-20 16:31发布

问题:

Im fairly new to SASS and I'm confused by the way lists work. I have a multidimensional list like this:

$stylethemes: {
  (15, bold, red),
  (12, normal, blue)
}

I now want a function that makes a class for each list in $stylethemes and then puts the values of that list into that class. The output I want from the above list is this:

.theme1{
   font-size: 15;
   font-weight: bold;
   color: red;
}

.theme2{
   font-size: 12;
   font-weight: normal;
   color: blue;
}

Can anyone show me how I can do this? Thanks in advance.

回答1:

The code to produce the desired results would look like this:

$stylethemes: (
  (15, bold, red),
  (12, normal, blue)
);

@for $i from 1 through length($stylethemes) {
  .theme#{$i} {
    font-size: nth(nth($stylethemes, $i), 1);
    font-weight: nth(nth($stylethemes, $i), 2);
    color: nth(nth($stylethemes, $i), 3);
  }
}

However, you'll find this isn't particularly flexible. You're better off using mappings for the property/values so that you don't have to guarantee a specific order:

$stylethemes: (
  (font-size: 15, font-weight: bold, color: red),
  (font-size: 12, font-weight: normal, color: blue)
);

@for $i from 1 through length($stylethemes) {
  .theme#{$i} {
    @each $prop, $val in nth($stylethemes, $i) {
      #{$prop}: $val;
    }
  }
}

Or

$stylethemes: (
  theme1: (font-size: 15, font-weight: bold, color: red),
  theme2: (font-size: 12, font-weight: normal, color: blue)
);

@each $theme, $properties in $stylethemes {
  .#{$theme} {
    @each $prop, $val in $properties {
      #{$prop}: $val;
    }
  }
}


回答2:

Youa re basically asking us to solve your pboelm, but fine, since SASS is very deep and fun to use and can be a bit daunting with its lack of map looping functions. I changed a couple of things but this is essentially it:

// first off, I decided to make your style themes a SASS map. This is useful because your
// your theme will be intricately linked to its name, making it easier to read
// you could to the same with the values, but for now I'll count them.
$stylethemes: (
  theme-1 : (15, bold, red),
  theme-2 : (12, normal, blue)
);

// first, we need to create a regular list we can loop through with a for loop
// map-keys returns a list we can use for that
$allthemes : map-keys($stylethemes);

// then we can run through all the themes by finding the theme name from the above list
@for $var from 1 through length($allthemes) {
    // heres how we get the theme name
    $theme : nth($allthemes, $var);
    // heres how we get the values stored in your SASS map
    $this : map-get($stylethemes, $theme);
    // then I assign all your variables to vars, but its not necessary
    $size : nth($this, 1);
    $style : nth($this, 2);
    $color : nth($this, 3);
    // now print the theme name as a classname
    .#{$theme}{
       // then print the values - you could also use the above nth($this, n) to get them.
       font-size: $size;
       font-weight: $style;
       color: $color;
    }
}

I got all the function info from the SASS documentation site: http://sass-lang.com/documentation/Sass/Script/Functions.html, so have a look around there, there is a dedicated section for lists and maps. Have a look at lists and maps as they will be very useful for this kind of thing.



标签: sass