SCSS precompilation: variable undefined (Rails 4)

Scenario

In /products.css.scss :

@import 'partials/colors';
@import 'partials/boxes';

#wrapper {}

      

In /partials/_colors.css.scss :

$light-gray: #ccc;

      

In /partials/_boxes.css.scss :

#box-light-gray {
  background-color: $light-gray;
  width: 50px;
  height: 50px;
}

      

Problem

This happens in rake assets:precompile

, in the environment production

:

Sass :: SyntaxError: Variable Undefined: "$ light-gray". (in / partials / _boxes.css.scss: 2)

My thoughts

The file /partials/_boxes.css.scss does not have a variable $light-gray

by itself - and here I have to agree with rake assets:precompile

. The point is this: how to make it rake

recognize the injection $light-gray

in /partials/_boxes.css.scss ?

I think it rake

doesn't match the puzzle points because it doesn't know how SCSS works. I feel like I am missing something SCSS related to pair with rake

.

+3


source to share


2 answers


This is a tricky issue with the current version of Sprockets and sass-rails. You might think that the lines *= require

in your file application.css

would load the variables in order so that they are available across all scss files, but they are not. Here's what the Rails Guide pipeline says about it :

If you want to use multiple Sass files, you should generally use Sass @import instead of these Sprockets directives. With the Sprockets Directive, all Sass files exist within their own scope, variables or mixins are only available in the document they were defined in. You can also do file aliasing using @import ", and @import" * / * "to add an entire tree equivalent to how require_tree works. See the sass-rails documentation and important caveats for more information.

In other words, you have two options:

  • @import

    your variables in each file as needed.
  • Use @import

    in your file application.css.scss

    instead*= require



If you go to the first option, just skip @import 'partials/colors';

to the beginning _boxes.css.scss

.

In the second option, you just need @import

your stylesheets application.css.scss

one time (in the correct order), then your variables in mixins will be available to all stylesheets. You are still using the asset pipeline here, so the precompilation will still work fine, but you allow the sass-rails

sasa magic to work. Yours application.css.scss

will look something like this:

@import 'partials/colors';
@import 'partials/*';
@import '*';

      

Be warned that there is currently a bug in sass-rails. If you have stylesheets .erb

, sass-rails will not be able to import them from a template if they are in a separate folder.

+7


source


Without changing your scss I think your best option is to place @import 'partials/colors';

in your file _boxes.css.scss

. The biggest drawback @import

is that it contains an additional HTTP request, however, since you are precompiling your parsing, I'm not entirely sure if this is still a problem.

Possible refactoring option:

_colors.css.scss

$light-gray: #ccc;

      

_box-sizes.css.scss



.small-box{
   width: 50px;
   height: 50px;
}

      

products.css.scss

@import 'partials/colors';
@import 'partials/box-sizes';

.small-light-grey-box{
    @extend .small-box
    background-color: $light-gray;
}

      

Again, this is just an example. There are many ways to refactor your scss and html to get the desired result.

+2


source







All Articles