css labs sass

Structure Your SASS Files With @import

For my first blog post at Pivotal, I decided to pick a small topic that I am pretty confident about: why to structure your SASS files with the @import rule.

If you are still using Sprockets directives in Asset Pipeline to combine your SASS files, I highly recommend to switching over to using the SASS @import rule instead.

Consider this simple CSS setup:

application.css (using Sprockets Directives)

/*
 *= require partials/variables
 *= require partials/typography
 *= require partials/elements

 *= require vendor/grid
 *= require vendor/mixins

 *= require pages/home
 *= require pages/listing
 *= require pages/detail
 */
(NOTE: I am intentionally not using "*= require_tree" right now.)

The same setup using SASS @import rule would look like this:

application.sass (using SASS @import)

@import partials/variables
@import partials/typography
@import partials/elements

@import vendor/grid
@import vendor/mixins

@import pages/home
@import pages/listing
@import pages/detail

The main advantages come from the fact that SASS @import creates a global namespace, while the Sprockets directives do not.

Using the Sprockets Directives method, working in the ‘pages/home.sass’ file, you have to do this:

home.sass (using Sprockets method)

@import partials/variables
@import partials/typography
@import vendor/mixins

.home-layout
  color: CornflowerBlue

While, using the SASS @import method, you don’t need to re-@import at all. All files @import’ed lower in the order already have access to all the variables and mixins defined in the files loaded above it in application.sass.

Some may not call this a “problem”, but aside from being annoying to do every time, there also a more serious problem; any file that contains renderable CSS (anything excluding variables, placeholders and mixin definitions) will be rendered every time it is @import’ed. This can quickly grow your final CSS output (I’ve seen some minified CSS > 1MB because of this error) and create a mass of duplicate selectors, putting undue load on the browser.

Softer Benefits:

  • Using the @import global namespace creates a Whorfian effect where the developers on the team tend to define and reuse their variables where they should (in the variables files), and not in more specific files. For example, z-indexes can become a nightmare if not defined in a global variables file.
  • Compilation will speed up a bit in development, because it won’t have to re-compile all the vendor mixins every time each partial @import’s it.
  • SASS @import syntax is easier to read than the Sprockets CSS comments syntax, IMO.

And Lastly…

Just to appeal to higher authority (why not?), this practice is recommended on the Rails Asset Pipeline guide:

And in CAPS on the sass-rails gem readme:

Sass-rails gem advice on @import

Thanks for reading!