Search code examples
cssreactjssassmixinsscss-mixins

Dynamically nest CSS Classes in SASS


I am trying to create dynamically nested classes in SASS. I am using React 18 and SASS 1.62 (Craco).

I have a scss file that needs to look like this

.gridRow.scss

.root {
  &.row-cols-auto>* {
    flex: 0 0 auto;
    width: auto;
  }

  &.row-cols-1>* {
    flex: 0 0 auto;
    width: 100%;
  }

  &.row-cols-2>* {
    flex: 0 0 auto;
    width: 50%;
  }

  &.row-cols-3>* {
    flex: 0 0 auto;
    width: 33.3333333333%;
  }

  &.row-cols-4>* {
    flex: 0 0 auto;
    width: 25%;
  }

  &.row-cols-5>* {
    flex: 0 0 auto;
    width: 25%;
  }

  &.row-cols-6>* {
    flex: 0 0 auto;
    width: 16.6666666667%;
  }
}

I want to create dynamically all these CSS classes. For that, I wrote the following mixin:

$grid-row-columns: 6;

@mixin create-row-cols () {
  &.row-cols-auto>* {
    flex: 0 0 auto;
    width: auto;
  }

  @for $i from 1 through $grid-row-columns {
    &.row-cols-#{$i}>* {
      flex: 0 0 auto;
      width: math.percentage(math.div(1, $i));
    }
  }
}

Yet, when I use the mixin as:

.root {
 @include create-row-cols()
}

It doesn't work.

Does anyone know how to fix it? I am out of ideas now. Thanks.

I tried to hard code the values, which worked.

I tried to inspect the bundled css file but couldn't find it, maybe peaking to it will show what it actually is created.

I tried to refactor the mixin function to look for typos, but I couldn't find any.


Solution

  • I think the reason it didn't work is because your SASS version is a little low. Try to upgrade may resolve the issue.

    Or another solution: use width: math.percentage(1/$i); instead of width: math.percentage(math.div(1, $i));.

    Below is my test:

    enter image description here

    My sass version is:

    enter image description here

    The dart-sass is:

    enter image description here

    And it works.

    So I still believe your sass version is not high enough.