Reputation: 5011
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;
}
It happens on rake assets:precompile
, in production
environment:
Sass::SyntaxError: Undefined variable: "$light-gray". (in /partials/_boxes.css.scss:2)
The file /partials/_boxes.css.scss doesn't have the variable $light-gray
by itself – and here I have to agree with rake assets:precompile
. The point is: how do I do to make rake
recognize the injection of $light-gray
into /partials/_boxes.css.scss?
I think rake
is not matching the points of the puzzle because it doesn't know how SCSS works. I feel I'm missing something related to SCSS in couple with rake
.
Upvotes: 4
Views: 4630
Reputation: 3513
This is a tricky problem with the current version of Sprockets and sass-rails. You would think that the *= require
lines in your application.css
file would load the variables in order so that they would be available to all scss files, but it does not. Here is what the asset pipeline Rails guide says about it:
If you want to use multiple Sass files, you should generally use the Sass @import rule instead of these Sprockets directives. Using Sprockets directives all Sass files exist within their own scope, making variables or mixins only available within the document they were defined in. You can do file globbing as well using @import "", and @import "*/*" to add the whole tree equivalent to how require_tree works. Check the sass-rails documentation for more info and important caveats.
In other words, you have a two choices:
@import
your variables in each file as you need them@import
in your application.css.scss
file instead of *= require
If you go with the first option, just drop in @import 'partials/colors';
to the top of _boxes.css.scss
.
With the second option, you just need to @import
your stylesheets in your application.css.scss
once (in the proper order), then your variables in mixins will be available to all stylesheets. You're still using the asset pipeline here so precompilation will still work fine, but you're letting sass-rails
work its sass magic. Your application.css.scss
would look something like this:
@import 'partials/colors';
@import 'partials/*';
@import '*';
Be warned though, there is currently a bug with sass-rails. If you have .erb
stylesheets, sass-rails won't be able to import them by wildcard if they're in a seperate folder.
Upvotes: 8
Reputation: 8846
Without modifying your scss, I think your best option is to put @import 'partials/colors';
in your _boxes.css.scss
file also. The biggest drawback with @import
is that it includes an additional http request, however since you are precompiling your assests I'm not entirely sure that is still an issue.
Potential 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 countless ways you could refactor your scss and html to get the desired outcome.
Upvotes: 2