skip to Main Content

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.

2

Answers


  1. Chosen as BEST ANSWER

    Ultimately, the problem wasn't in the SCSS but the react file. It wasn't hitting the nail due to improper handling with classNames.

    An example of a fixed component:

    const Row = React.forwardRef(({
      as: Component,
      className,
      rowCols,
      g,
      gx,
      gy, 
      children,
      ...props
    }, ref) => {
    
        // parse possible {XS: 4, ...} to {GridRow-row-cols-xs-4: 4, ...}
      const mappedRowCols = _.isObject(rowCols) ?
        _.mapKeys(rowCols, (value, key) => [styles[`row-cols-${_.toLower(key)}-${value}`]]) :
        rowCols && {[styles[`row-cols-${rowCols}`]]: rowCols};
    
      const mappedGutters = _.isObject(g) ?
        _.mapKeys(g, (value, key) => [styles[`g-${_.toLower(key)}-${value}`]]) :
        g && {[styles[`g-${g}`]]: g};
    
      const mappedGuttersX = _.mapKeys(gx, (value, key) => [styles[`gx-${_.toLower(key)}-${value}`]]);
      const mappedGuttersY = _.mapKeys(gy, (value, key) => [styles[`gy-${_.toLower(key)}-${value}`]]);
    
      return (
        <Component
          ref={ref}
          {...props}
          className={classNames(
            styles.root,
            mappedGuttersX,
            mappedGuttersY,
            mappedGutters,
            mappedRowCols,
            className)}
        >
          {children}
        </Component>
      );
    });
    

  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search