template.scss could import _common.scss using @import "common" but is it possible for more_styles.scss to import _common.scss? I tried a few different things including @import "../sub_directory_a/common" and @import "../sub_directory_a/_common.scss" but nothing seems to work.

13 Answers
13

Looks like some changes to SASS have made possible what you've initially tried doing:

@import "../subdir/common";

We even got this to work for some totally unrelated folder located in c:\projects\sass:

@import "../../../../../../../../../../projects/sass/common";

Just add enough ../ to be sure you'll end up at the drive root and you're good to go.

Of course, this solution is far from pretty, but I couldn't get an import from a totally different folder to work, neither using I c:\projects\sass nor setting the environment variable SASS_PATH (from: :load_paths reference) to that same value.

It is "far from pretty"! But this answer is getting lots of upvotes. Is this really considered a better practice than -I? If that pathname changes there will be lots of searching and replacing; and it requires the same local folder structure of anyone sharing the .scss
– WiseOldDuckFeb 4 '16 at 19:58

8

"Just add enough ../ to be sure you'll end up at the drive root and you're good to go." Hahaha that made my day.
– Steve HarrisonJan 25 '17 at 1:47

3

I advice ignoring this answer completely. Unfortunately it's one of many SO questions, which are answered incorrectly with up votes. If you want your code to break easily, use it. If you want a robust solution, see my answer below.
– adi518Jun 21 '17 at 14:26

2

@adi518: I could argue about your statement "If you want your code to break easily, use it." The given solution has been working for us ever since (so almost 4 years now) and has not broken anything. I feel this is one of those solutions that might be somewhat dirty but get the job done quickly and without digging too deep into the internals of some of the tools involved.
– OliverJun 21 '17 at 21:20

Working doesn't mean it's correct. Config provided you with a way to resolve paths. You should have used that instead.
– adi518Jun 22 '17 at 8:10

Agree with Splaktar. From sass-loader docs: webpack provides an advanced mechanism to resolve files. The sass-loader uses Sass's custom importer feature to pass all queries to the webpack resolving engine. Thus you can import your Sass modules from node_modules. Just prepend them with a ~ to tell webpack that this is not a relative import... It's important to only prepend it with ~, because ~/ resolves to the home directory.
– AnthonyNov 12 at 10:03

Importing a .scss file that has a nested import with a different relative position won't work. the top proposed answer (using a lot of ../) is just a dirty hack that will work as long as you added enough ../ to reach the root of your project's deployment OS.

Add the target SCSS path as a search target for SCSS compiler.
This can be achieved by adding the stylesheets folder into the scss config file, this is function of the framework you are using,

use :load_paths at config.rd for compass-based frameworks (Ex. rails)

use the following code at scss-config.json for fourseven/meteor-scss

{
"includePaths": [
"{}/node_modules/ionicons/dist/scss/"
]
}

Use absolute paths (vs. relative paths).

Example, with fourseven/meteor-scss, you can use {} to highlight
top level of your project as per the following examplI

OP's practice seems irregular. A shared/common file normally lives under partials, a standard boilerplate directory. You should then add partials directory to your config import paths in order to resolve partials anywhere in your code.

When I encountered this issue for the first time, I figured SASS probably gives you a global variable similar to Node's __dirname, which keeps an absolute path to current working directory (cwd). Unfortunately, it does not and the reason why is because interpolation on an @import directive isn't possible, hence you cannot do a dynamic import path.

Appendix

You are likely to run into cases where you want to import a CSS file in an embedded manner, that is, not via the vanilla @import directive CSS provides out of the box, but an actual merge of a CSS file content with your SASS. There's another question, which is answered inconclusively (the solution does not work cross-environment). The solution then, is to use this SASS extension.

Once installed, add the following line to your config: require 'sass-css-importer' and then, somewhere in your code: @import 'CSS:myCssFile';

Notice the extension must be omitted for this to work.

However, we will run into the same issue when trying to import a CSS file from a non-default path and add_import_path does not respect CSS files. So to solve that, you need to add, yet another line in your config, which is naturally similar:

add_import_path Sass::CssImporter::Importer.new('sub_directory_a')

Now everything will work nicely.

P.S.,
I noticed sass-css-importer documentation indicates a CSS: prefix is required in addition to omitting the .css extension. I found out it works regardless. Someone started an issue, which remained unanswered thus far.

To define the file to import it's possible to use all folders common definitions. You just have to be aware that it's relative to file you are defining it. More about import option with examples you can check here.

I think Miikka's response was really what I was after but now I am curious about Compass too. Is the partials directory somehow specific to a particular project? Or would files put in the partials directory be available "globally," wherever Compass is used?
– spaaarky21Jul 5 '11 at 15:38

3

This doesn't answer the question at all.
– cimmanonDec 31 '15 at 13:51

As far i know if you want to import one scss to another its has to be a partial. When you are importing from different directory name your more_styles.scss to _more_styles.scss. Then import it into your template.scss like this @import ../sub_directory_b/_more_styles.scss. It worked for me. But as you mentioned ../sub_directory_a/_common.scss not working. That's the same directory of the template.scss. That is why it wont work.