Home > Net >  Dynamic function parameter in for loop
Dynamic function parameter in for loop

Time:10-28

I'm trying to generate CSS variables in a for loop by calling a function that gets colors from a map. I created a map with colors, like this:

$shade-colors: (
    100: #1A1A1A,
    200: #2E2E2E,
    300: #495057,
    400: #6c757d,
    500: #adb5bd,
    600: #cccccc,
    700: #dee2e6,
    800: #e9ecef,
    900: #ececec  
);

To get colors from this (and other maps), I'm using this function:

@function color($cat, $color, $shade: base) {
    @if ($cat == 'theme') {
        @return map-get($theme-colors, $color, $shade);
    }
    @else if ($cat == 'shade') {
        @return map-get($shade-colors, $color);
    }
    @else {
        @return map-get($cat, $color, $shade);
    }
}

I would like to generate the CSS variables dynamically out of the $shade-colors map through a for loop, like this:

@for $i from 1 through 9 {
    $i: #{$i}00;
    $val: color('shade', #{$i});
    --color-shade-#{$i}: #{$val};
}

For some reason I can not get this to work. The problem occurs in the second argument from the function call. Using a static value works, but it's not working with the dynamically generated 100 through 900 as I would expect. Heres a pen representing this issue: https://codepen.io/ikmaakt/pen/KKvqMMg

CodePudding user response:

One way to do it is to iterate over map directly instead of having separate for loop with some rather complex logic for building name and getting the value

Example for generating variables with iterating over $shade-colors:

:root {
  @each $name, $color in $shade-colors {
    --color-shade-#{$name}: #{$color};
  }

If you really want to do it your way, I would suggest creating an array and iterate over it with @each:

$weights: 100, 200, 300, 400, 500, 600, 700, 800, 900;

:root {
  @each $weight in $weights {
    --color-shade-#{$weight}: color('shade', #{#{$weight});
  }
}
  • Related