sass / dart-sass

The reference implementation of Sass, written in Dart.
https://sass-lang.com/dart-sass
MIT License
3.9k stars 352 forks source link

Shadowed variables override outer scope #2301

Closed alecgibson closed 1 month ago

alecgibson commented 1 month ago

Consider this SCSS:

div {
  $background: blue;

  span {
    $background: green;
    background: $background;
  }

  background: $background;
}

According to the docs:

Local variables can even be declared with the same name as a global variable. If this happens, there are actually two different variables with the same name: one local and one global. This helps ensure that an author writing a local variable doesn’t accidentally change the value of a global variable they aren’t even aware of.

Given that, I'd expect the compiled CSS:

div {
  background: blue;
}
div span {
  background: green;
}

But what I actually get is:

div {
  background: green;
}
div span {
  background: green;
}

Using v1.77.8

Playground

alecgibson commented 1 month ago

Or perhaps the docs truly mean "global"?

If I have

$background: blue;

div {
  span {
    $background: green;
    background: $background;
  }

  background: $background;
}

It works as expected:

div {
  background: blue;
}
div span {
  background: green;
}

But I still find the original result highly surprising.

Goodwine commented 1 month ago

Or perhaps the docs truly mean "global"?

If I understand your question correctly, then yes. A variable is declared either global or local.

The part that may be confusing is that in Sass, a local variable is "shared" with all nested blocks. It is not shadowing the variable from the outer scope. Only the variables in the global scope can be shadowed, otherwise they are "shared". So when you set the value of the variable to green, it is not creating a new variable, but assigning the value to the existing local variable.

This is necessary because in Sass an assignment statement has the same syntax as a variable declaration statement, unlike languages like C or Dart where assignment and variable declaration have a distinct syntax.