DEV Community

Tyler Smith
Tyler Smith

Posted on • Edited on

Scoping variables to a single file in Scss without @use

Traditionally, any variable declared outside of a selector in Scss has a global scope, and variables declared inside of a selector have a local scope:

$global-variable: 10px;

.some-class {
  $local-variable: 5px;
}
Enter fullscreen mode Exit fullscreen mode

Global variables can cause problems in large projects because you can accidentally overwrite them from any file.

For example, let's say you had a variable called $grid-gutter-width with a value of 16px in a _variables.scss file. You could accidentally override that variable in another file:

// _some-other-file.scss

$grid-gutter-width: 40px;

.fancy-column {
  padding-left: $grid-gutter-width * 0.5;
  padding-right: $grid-gutter-width * 0.5;
}

.fancy-row {
  margin-left: $grid-gutter-width * -0.5;
  margin-right: $grid-gutter-width * -0.5;
}
Enter fullscreen mode Exit fullscreen mode

This would overwrite the $grid-gutter-width variable for every subsequent use, setting the value to 40px instead of 16px. Something like this could potentially break the entire layout of the site.

While new versions of Scss prevent global scoping by using the @use rule, LibSass-based versions of Scss like node-sass and Hugo's Scss don't support this feature.

Limiting the scope using @at-root

So how can you scope a variable to a single file in older versions of Scss? You can wrap the file in an @at-root rule:

@at-root {
  $grid-gutter-width: 40px;

  .fancy-column {
    padding-left: $grid-gutter-width * 0.5;
    padding-right: $grid-gutter-width * 0.5;
  }

  .fancy-row {
    margin-left: $grid-gutter-width * -0.5;
    margin-right: $grid-gutter-width * -0.5;
  }
}
Enter fullscreen mode Exit fullscreen mode

The @at-root rule in Scss causes everything within it to be emitted at the root of the document instead of using the normal nesting. It's typically used to escape from a nested context, but in the example above we can use it to enclose a new local scope.

By setting the$grid-gutter-width variable within the @at-root block, we can overwrite its value in that file without overwriting it elsewhere in your stylesheet.

Top comments (0)