As discussed up to this point, it is the desire of many developers to break down their CSS into smaller, more manageable resource files. Even SMACSS clearly advocates for breaking down all of it's core types and modules into separate .css
files. There is a huge flaw in this since vanilla CSS does not support the aggregation of these resources. You are either left with linking multiple CSS resources, using the non-performant @import
native CSS feature or looking to more complex solutions.
Sass' solution to the problem is to natively support partials. Sass can be broken into smaller, more manageable resource files and by default any .sass
or .scss
fill will be processed into CSS.
|- sass/
|--- buttons.scss
|--- forms.scss
|--- reset.scss
|--- typography.scss
Will output the following:
|- stylesheets/
|--- buttons.css
|--- forms.css
|--- reset.css
|--- typography.css
Frameworks like Rails will take all these individual CSS files and compress them into a single CSS file for production, but we are not all Rails developers. Not to mention that the Rails documentation states that this solution was not designed for multiple Sass files and you should use Sass' native @import
rule instead of Rails' Sprockets directives.
Partials are a powerful weapon in the Sass arsenal. Simply put, any file that has an underscore before the name, _partialName.scss
, will not be processed into a .css
file by itself. It is required to be imported into a file that will be processed into CSS. Editing the previous example, we will make each Sass file a partial and use a manifest file to aggregate the partials using the @import
rule.
|- sass/
|--- _buttons.scss
|--- _forms.scss
|--- _reset.scss
|--- _typography.scss
|--- application.scss
Will output the following:
|- stylesheets/
|--- application.css
At this level of the file structure example, the only file that is processed into CSS is the application.css
manifest. It's here where all your custom add-ons, configs, elements, modules, views, mixins, extends, etc., are all imported and processed into a production style-sheet. It is important that this file be kept devoid of any presentational CSS rules.
An example manifest file would only contain instructions and the imported Sass files as illustrated in the following.
// App Config - this is where most of your magic will happen
// --------------------------------------------------
@import "config"; // The config file sets the theme for the project
// Import core Sass libraries
// --------------------------------------------------
@import "lib/bourbon/bourbon";
@import "lib/colors/manifest";
@import "lib/typography/manifest";
// Standard CSS reset stuff here
// --------------------------------------------------
@import "reset";
This is not to say that application.scss is the only Sass manifest file. Manifests can import other manifests. A pattern that helps to keep the application.scss manifest easy to read while keeping sub-directory files nicely organized.
Manual manifests are just that, manual management of imported Sass files from sub-directories. This is a good practice to follow when you need specific control over the inheritance of files. Example, rule A needs to come before rule B in the output cascade.
Glob-imports on the other hand is a way for you to simply point to a directory in your manifest, @import "directory/*"
; and Sass will import all the files in alphabetical order. This is great for a directory of mixins or functions that simply need to be loaded in memory for Sass to process the CSS. If you want to use the glob function but require a specific order, a naming convention like _01-mixin.scss
could work as well.
If you are a Rails developer, this feature is made available to you via the sass-rails Gem. If you are not using Rails, Chris Eppstein has made this feature available to all users via a plug-in Ruby Gem, Sass globbing.