Sass: The @import Directive

One way to writer DRYer code is to separate concerns and keep related code in separate files. This allows you to maintain code in one file as opposed to maintaining the same code over several or many files.

Naturally to be able to keep your code in separate files, you need to be able to combine them all back together. With CSS (and Sass) you can use the @import directive to include the content of one file in another.

For the past two weeks I’ve talked about @-rules and directives in Sass. Last week I focused on the @media directive. Today and next week I want to talk about @import.

The CSS @import Rule

The @import directive is a CSS @-rule that was briefly popular before falling out of favor due to performance issues. If you’ve been developing websites for awhile, you may remember using it a number of years ago.

Using CSS’ @import you could include stylesheets inside other stylesheets. The included files could either be located on the same server or included with a URL to a directory on another server.

[code type=css]
@import “style.css”;
@import “css/style.css”;
@import url(“http://domain.com/css/styles.css”);
[/code]

While this allowed developers to import CSS files into other CSS files, the practice fell out of favor mainly because of a performance hit in @import, but some other issues as well. Sass removes the performance hit because the @import statements are removed from your Sass code when it compiles to CSS.

The Sass @import Directive

Sass extends the CSS @import rule so that it works with .scss and .sass files. It imports the file referenced and any variables or mixins that are defined in the imported file can be used in the main file.

[code type=css]
@import “typography.scss”;
[/code]

Assuming there’s a file typography.scss in the current directory, the contents of typography.scss will replace the @import statement.

Sass makes it even simpler. If you forget to include the extension, it will look for a file with the same name and either a .scss or .sass extension.

[code type=css]
@import “typography”;
[/code]

The statement above would find either typography.scss or typography.sass in the same directory as the file importing the typography styles.

By default Sass will include the content of the file being imported in place of the @import statement, but there are times when Sass will compile to a CSS @import rule. In other words you’ll end up with an @import in the .css file instead of the code in the referenced file. Sass will compile to an @import if:

The file’s extension is .css

The filename begins with http://

The filename is a url()

The @import has any media queries

Given the previously mentioned issues with the CSS @import rule, you probably don’t want this and always want the content in the files to be included directly. As long as none of these four conditions exist the content of the file will be imported.

You aren’t limited to a single @import statement. You can use as many as you like. For example importing three different files will import the content of each file in the same order they are referenced.

[code type=css]
@import “typography.scss”;
@import “color.scss”;
@import “layout.scss”;
[/code]

You don’t have to use multiple @import statements to include multiple files. You can import multiple files in a single @import statement.

[code type=css]
@import “typography.scss”, “color.scss”, “layout.scss”;
[/code]

All three files would again be imported in the order listed.

Partials

Sass compiles all the .scss or .sass files inside the directory it’s watching. However, when your goal is to import a file, you don’t need to compile it directly.

You can tell Sass not to compile a file through the file’s name. If you add an underscore to the start of the file name, Sass won’t compile it. If you don’t want color.scss to compile to .color.css, name the file _color.scss instead. Files named this way are called partials in Sass terminology.

You can skip the underscore when referencing a file inside an @import rule, the same way you can skip the extension.

[code type=css]
@import “color”;
[/code]

Sass understands to import the file _color.scss (or _color.sass) from the current directory, if present.

The ability to tell Sass which files to compile and which to only include in other files, allows you to create a file and directory structure that’s easier for you to maintain, without ending up with a lot of extra CSS files.

Nested @import Directives

You’ll typically include your @import statements at the top of the the importing file, but you can nest @import within other Sass rules similar to the way you can nest @media directives.

Let’s say you create a partial named _nav-bkgd.scss that only includes the background color of your navigation items.

[code type=css]
li {
background-color: #ccc;
}
[/code]

You can import the partial file directly inside the block of code that styles your global navigation, say inside a class named .global-nav.

[code type=css]
.global-nav {
@import “nav-bkgd”;
}
[/code]

Assuming the two files are located in the same folder, the code would compile to:

[code type=css]
.global-nav li {
background-color: #ccc;
}
[/code]

You can’t import everything this way. For example directives like @mixin and @charset, which are allowed only at the base level of a document are not allowed inside a nested @import.

You also can’t nest an @import within mixins or control directives, both of which I’ll cover in the future. I’ll cover mixins later in this series and control directives in a series later in the year.

File and Folder Structure with @imports and Partials

There are a lot of different ways you can organize your files and folders using @import rules and partials to help make your project more maintainable. I’ll show you more next week, but let me at least show you one way today. I picked up from an article John Long wrote for The Sass Way.

I used this directory structure when building a small site for a client a few years ago. My .scss directory contained three folders (modules, partials, and vendor), each with one or more files inside. There’s also one top level file, main.scss.

modules/

_color.scss

_typography.scss

partials/

_base.scss

_navigation.scss

vendor/

_ico-moon.scss

main.scss

The vendor folder holds any code you get from 3rd parties. In my example there’s a file called _ico-moon.scss, which comes from vendor Ico Moon.

The partials folder includes code that will be imported in place into another file and then compiled with the rest of the code in that file. In my partials folder I have some general styles in _base.scss and navigation specific styles in _navigation.scss that I want to import and compile.

Technically the files in all three folders are partials as they all include an underscore, but partials is the name given to this folder in John’s structure. Hopefully it’s not too confusing. Feel free to change the name of the folder in your project to something else if it is confusing. The main point is these files contain code what will be included into another file and then compiled with that file.

The modules folder includes code that won’t be compiled. It includes things like mixins and functions and variables. In my case, the two files _color.scss and _typography.scss both contained variables and nothing else.

A bit off topic, but I used the variable files to quickly show my client variations on the design. Instead of a single _color.scss file, I things like had _color-red.scss, _color-green.scss, _color-blue.scss where the color was the dominant color in the color scheme. It was a quick way to show the design with color variations and type variations.

Speaking of importing files, that’s what the main.scss file in the directory does. At the very top of the file are a series of @import statements.

@import “modules/color”;

@import “modules/typography”;

@import “partials/base”;

@import “partials/navigation”;

@import “vendor/ico-moon”;

Note that because the files are all technically partials, you don’t need to include the underscore or the file extension when referencing the file.

You can easily find more ways to organize your Sass files and folders in a project and I’ll show you some next week. Hopefully the simple structure above gets you thinking about a structure that would work for you.

Closing Thoughts

The @import rule is one CSS @rule we’ve been told not to use for years, but all of its issues go away when you use the extended Sass @import directive.

You can help make your code more maintainable by using @import and breaking down large files into smaller and more focused files that get imported into other files and eventually one top level file that will be compiled into CSS.

There’s no one way or right way to set up the structure, though there are some common threads to the different structures people use. Next week I’ll show you a few more structures and point you to some resources with more details for how and why they were created.