scssphp: for loop fails on undefined vars

My project need compiles based on theme colors. This means i have to add vars dynamically to override scss vars.

The project uses Foundation sites (6.1) scss. But some loops return undefined var errors:

@for $i from 1 through $grid-column-count {
  // Column width
  .#{$-zf-size}-#{$i} {
    @include grid-col-size($i); // this $i is undefined in the compiler
  }

  // Source ordering
  @if $i < $grid-column-count {
    .#{$-zf-size}-#{$push}-#{$i} {
      @include grid-col-pos($i); // this $i is undefined in the compiler
    }

    .#{$-zf-size}-#{$pull}-#{$i} {
      @include grid-col-pos(-$i); // this $i is undefined in the compiler
    }
  }

  // Offsets
  $o: $i - 1;
  .#{$-zf-size}-#{$offset}-#{$o} {
    @include grid-col-off($o);
  }
}

I’ve added comments where the variables are undefined. I’ve noticed it with a similar situation:

// Heading sizes
@each $size, $headers in $header-sizes {
  @include breakpoint($size) {
    @each $header, $font-size in $headers {
      #{$header} {
        font-size : rem-calc($font-size); // this $font-size var is undefined
      }
    }
  }
}

So it seems to fail within loops and inside mixin includes

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 10
  • Comments: 49 (6 by maintainers)

Commits related to this issue

Most upvoted comments

If someone’s interested, I’d pay 50€ for fixing this and making foundation 6.3.0 compile with flex grid. 100€ if the fix is merged before sunday 12th.


I have moved to NodeJS solution so the 50€ is no longer in play but that 100€ is still worth it for me(only 3 days left though).

Further investigation shows that variables were being set properly in the for environment, and that the whole structure of the system doesn’t pass variables to children, but rather appends the child environment to the parent environment tree.

This led me to Compiler::get(), where environments are popped off the tree until the appropriate one is found. There is a little bit of extra logic here to essentially “fall out” of the tree under certain conditions, skipping variables at higher levels and going straight to the root environment. In doing so, $i was never resolved, because it was skipped.

Solution: comment out Compiler.php line 3122 $nextIsRoot = true;

This also solves the issue with $gutters, and the whole of Foundation 6.3.1 now compiles, and seems to render the correct CSS when compared to the distribution file (whitespace aside).

I’m sure, however, there are side effects to this change. I presume the nextIsRoot logic was placed there for a reason. Perhaps there are situations where a variable is defined at one of those skipped levels of the tree that is also defined at root, and that’s the value we really want, but I can’t think of an example at the moment. I would think, though, if you redefine a variable in a narrower scope, then call a mixin or include, it would make sense to use that value, not the root value, for all child scopes… does this jive with SCSS spec?

Hey @darknailblue,

Thanks for pointing this out, though I also had to comment out “@include foundation-flex-classes” to get a successful transpilation.

Thanks for the suggestion too, though, for now, I’m going to stick with using a combination of nodemon, node-sass, and browsersync for development. scssphp is by far the fastest transpiler I’ve come across, so I hope this bug can be remedied soon.

EDIT: grammar

Could someone please review and comment on the following patch?

https://github.com/leafo/scssphp/compare/master...FMCorz:issue-446

It’s clearly not ready to be merged, but I just wonder if I’m heading in the right direction, and how I can improve the patch further so that this can be fixed.

In short, I think that the problem only arises when we’ve got two @include leading to resolving the variables of a function call. Because the environments of both @include are marked as mixin the variable resolution stops.

Ultimately I think that the function resolving the variables should be given an appropriate scope to start with rather than changing the variable resolution, but I need some guidance as to how to do this.

Cheers!

This is now fixed and work as expected in the initial test case (can be closed @robocoder )

Working on this now so I can use Foundation 6.3.1.

Looks like the for variable ($i in this case) value isn’t getting passed to it’s children.

The issues with $gutters is separate, I think; I was able to fix it by altering the .scss file slightly. Not ideal, but it got it out of the way so I could work on this.

@JumpLink Thanks. I had similar issues with leafo scssphp. Compile work fine with backwards-files but afterwards there are issues in boostrap colums, col-md-3 + col-md-9 e.g. aren´t side by side in a row.

I double checked it.