---
title: Sass Pathways
teaser: Handle multiple shared Sass layouts.
tags: sass,frontend,design
author: Ward Penney
published_on: 2016-05-31
---

Sass’s killer feature was truly the `@import` statement. When a Sass file is
imported, all the variables and mixins defined previously are now available in
any subsequent imported file. So, it is very good practice to define a single
top-level stylesheet that you link to from the `<HEAD>` of your page layout.
In a Rails implementation, this would likely be the `application.scss`. This
root file is then compiled into a CSS file of the same name. This file and its
subsequent imported partials I refer to as a **pathway.**

Although most sites do not require it, you may have more than one pathway.
There are several reasons for this, but they are often one of these:

* An “admin” view with a different design from the main site
* A live style guide with all of its extra CSS used to present the guide itself
* A new design in progress, with a corresponding separate layout
* A new pathway with refactored Sass and corresponding layout

When Sass compiles a pathway, it runs line-by-line from the top to the bottom
in linear fashion, delving recursively into any additional Sass partials
referenced with an `@import` statement. As Sass compiles the pathway, it loads
any variables, mixins, functions, placeholders and declarations into the global
namespace for that pathway. For example, if you define a variable at the top of
a pathway, it is available for use later in the pathway, including in other
files imported after the variable’s declaration.

### Partials

Pathways `@import` partials from the codebase, therefore it is not uncommon
for two pathways to share a common partial. For example, if you needed the same
color palette variables in a new design you were working on, you might `@import`
a `_colors.scss` partial in more than one pathway.

When naming Sass files, partials that are imported should begin with a leading
underscore. This is mostly a convention to let developers know this is not a
root Sass pathway file, and it is intended to be imported.

The important thing here is to understand that for a given Sass load path, the
namespace for declarations is global and the `@import` statement propagates
those declarations down into the partials.

### Seperate rendering and non-rendering Sass

In a previous post
[Separate Rendering Sass From Non-Rendering Sass](https://thoughtbot.com/blog/separate-rendering-sass-from-non-rendering-sass),
I covered how and why to separate these types of Sass.

As I mentioned in that article, variables, functions, and mixins should be
separated from Sass declarations that result in CSS being generated.
Separating the two gives you:

-   flexibility among Sass pathways,
-   clarity among imports without redundancy,
-   speed for the developer who may now assume access to all functions,
    variables, and mixins in a pathway

#### A simple file structure

Let's start with a simple setup that only separates rendering and non-rendering
Sass.

```tree
+-- application.scss
+-- base/
|   +-- _colors.scss
|   +-- _grid-settings.scss
|   +-- _icon-variables.scss
|   +-- _variables.scss
+-- patterns/
|   +-- _cards.scss
|   +-- _posts.scss
|   +-- _layouts.scss
|   +-- _lists.scss
|   +-- ...
```

And the root Sass pathway file:

```scss
application.scss

@import "base/colors";
@import "base/grid-settings";
@import "base/icon-variables";
@import "base/variables";

@import "patterns/cards";
@import "patterns/posts";
@import "patterns/layouts";
@import "patterns/lists";
```

The `base` folder holds all the non-rendering Sass. `patterns` folder holds all
the Sass declarations that will result in CSS. Whenever a new pattern is made,
the developer can safely assume they have access to any variable, mixin, or
function that exists.

### Easily create a new pathway

Suppose you made an additional Sass pathway:

```scss
new_lander.scss

@import "base/colors";
@import "base/grid-settings";
@import "base/icon-variables";
@import "base/variables";

@import "base/hero";
@import "base/signup-box";
```

Now your alternate layout and pathway has access to all of the variables,
functions, and mixins from the other pathway.

### Arguments against

*Not all patterns need all variables, functions, and mixins. Isn't this exposing
too much?*

True, not all patterns will use everything, but there is an unbalanced trade-off
in favor of always keeping variables, mixins, and functions in the global scope.

Benefits:

-   Easy creation of additional pathways.
-   Developer never has to search to see if what they need is already imported,
    which becomes difficult with `@import` statements in partials.
-   Chances for naming conflict among variables, functions, and mixins are
    lowered because conflicts are addressed as they are built.
-   No accidental duplicate `@import` of rendered CSS being sent down to the
    browser.
-   Very explicit root pathway file: you know what's in there and what isn't
    without having to go dig for it.
-   Negligible performance impact (if you have compile-time performance
    problems, try [libsass](https://github.com/sass/libsass) or remove use of
    `@extend` from deep nesting).
