Proper SCSS Asset Structure in Rails
Solution 1:
The problem with CSS is, you do not want to automatically add all files. The order of which your sheets are loaded and processed by the browser is essential. So you will always end up explicitly importing all your css.
As an example, lets say you have a normalize.css sheet, to get a default look instead of all the horrible different browser implementations. This should be the first file the browser loads. If you just randomly include this sheet somewhere in your css imports, it will then not only override the browser default styles, but also any styles defined in all css files that were loaded before it. This goes the same for variables and mixins.
After seeing a presentation by Roy Tomeij at Euruko2012 I decided for the following approach if you have a lot of CSS to manage.
I generally use this approach:
- Rename all existing .css files to .scss
- Remove all contents from application.scss
Start adding @import directives to application.scss
.
If you are using twitters bootstrap and a few css sheets of your own, you have to import bootstrap first, because it has a sheet to reset styles.
So you add @import "bootstrap/bootstrap.scss";
to your application.scss
.
The bootstrap.scss file looks like:
// CSS Reset
@import "reset.scss";
// Core
@import "variables.scss";
@import "mixins.scss";
// Grid system and page structure
@import "scaffolding.scss";
// Styled patterns and elements
@import "type.scss";
@import "forms.scss";
@import "tables.scss";
@import "patterns.scss";
And your application.scss
file look like:
@import "bootstrap/bootstrap.scss";
Because of the order of the imports, you can now use the variables, loaded with @import "variables.scss";
in any other .scss
file imported after it. So they can be used in type.scss
in the bootstrap folder but also in my_model.css.scss
.
After this create a folder named partials
or modules
. This will be the place of most of the other files. You can just add the import to the application.scss
file so it will look like:
@import "bootstrap/bootstrap.scss";
@import "partials/*";
Now if you make a bit of css to style an article on your homepage. Just create partials/_article.scss
and it will be added to the compiled application.css
. Because of the import order you can also use any bootstrap mixins and variables in your own scss files.
The only drawback of this method I found so far is, sometimes you have to force a recompile of the partial/*.scss files because rails wont always do it for you.
Solution 2:
Create the following folder structure:
+ assets
|
--+ base
| |
| --+ mixins (with subfolders as noted in your question)
|
--+ styles
|
--+ ...
In folder base
create a file "globals.css.scss". In this file, declare all your imports:
@import 'base/colors';
@import 'base/mixins/...';
@import 'base/mixins/...';
In you application.css.scss, you should then have:
*= require_self
*= depends_on ./base/globals.css.scss
*= require_tree ./styles
And as the last step (this is important), declare @import 'base/globals'
in every style file where you want to use variables or mixins. You might consider this overhead, but I actually like the idea that you have to declare the dependencies of your styles in every file. Of course, it is important that you only import mixins and variables in the globals.css.scss as they do not add style definitions. Otherwise the style definitions would be included multiple times in your precompiled file ...