592

Is there anyway to import a regular CSS file with Sass's @import command? While I'm not using all of the SCSS syntax from sass, I do still enjoy it's combining/compressing features, and would like to be able to use it without renaming all of my files to *.scss

alexronsaut
  • 140
  • 7
GSto
  • 41,512
  • 37
  • 133
  • 184
  • 5
    Yes, there is a way: just remove '.css' extension in css file path in @input statement :) (works for sass version >=3.2) – Kamil Kiełczewski Apr 26 '17 at 15:18
  • 1
    As of 2018, using [SASS `@import`](https://sass-lang.com/documentation/file.SASS_REFERENCE.html#import) in a regular CSS file should just generate a regular [CSS @import](https://developer.mozilla.org/en-US/docs/Web/CSS/@import). That means one more HTTP request and no combining or compressing. If some implementations behave differently then I'd say it's a non-standard feature that diverges from the language spec. – Álvaro González Nov 09 '18 at 13:47

15 Answers15

441

After having the same issue, I got confused with all the answers here and the comments over the repository of sass in github.

I just want to point out that as December 2014, this issue has been resolved. It is now possible to import css files directly into your sass file. The following PR in github solves the issue.

The syntax is the same as now - @import "your/path/to/the/file", without an extension after the file name. This will import your file directly. If you append *.css at the end, it will translate into the css rule @import url(...).

In case you are using some of the "fancy" new module bundlers such as webpack, you will probably need to use use ~ in the beginning of the path. So, if you want to import the following path node_modules/bootstrap/src/core.scss you would write something like
@import "~bootstrap/src/core".

NOTE:
It appears this isn't working for everybody. If your interpreter is based on libsass it should be working fine (checkout this). I've tested using @import on node-sass and it's working fine. Unfortunately this works and doesn't work on some ruby instances.

tftd
  • 16,203
  • 11
  • 62
  • 106
  • 1
    This seems to be implemented in `libsass` but when using the ruby implementation of sass, it seems that this syntax works, but only if you have `sass-css-importer` required. At least that's what I'm seeing. Can anyone else confirm this? – bsara Jul 28 '15 at 01:37
  • 7
    Are you sure you have the latest version of sass? I have been using this syntax for a while and it works fine with both `ruby` and `nodejs` interpreters. Have you checked if you're not placing an extension after the file name? The correct syntax is `@import "path/to/style/file` (without the `.css` extension) – tftd Jul 29 '15 at 12:54
  • 4
    I'm using ruby sass v3.4.18 (with Jekyll) according to my Gemfile.lock. Still seeing `Error: File to import not found or unreadable: cssdep/cssfile`. If I create a `cssdep/cssfile.scss` it suddenly works. So not a path issue, for some reason I still can't include '.css' files from SASS :( – thom_nic Aug 31 '15 at 15:06
  • Interesting - I'm using the latest ruby 2.2.3 and sass 3.4.17(which is the latest official right now) and I'm not experiencing any problems. Are you sure the path you're importing is accessible and correct? – tftd Aug 31 '15 at 16:04
  • 1
    `ruby -v` : `ruby 2.2.2p95 (2015-04-13 revision 50295) [x64-mingw32]` `sass -v` : `Sass 3.4.17 (Selective Steve)` not working here – Cyril CHAPON Sep 01 '15 at 07:58
  • Yep, you're right. I've just installed a VM with the same versions and it gives the same error which is quite strange as it used to work. You could try using node-sass - it works there. – tftd Sep 01 '15 at 11:22
  • 5
    Thank you for this! I was able to import normalize.css using node-sass with `@import "node_modules/normalize.css/normalize";` – Nick Jan 07 '16 at 18:38
  • Damn, I still cannot use this with Jekyll because it uses ruby sass :-( – Erik Berkun-Drevnig Feb 16 '16 at 05:14
  • This causes an error `File to import not found or unreadable` if you're trying to import a css file from a directory where there are files with the same name, but different extensions. – Betsy Dupuis Apr 28 '16 at 16:16
  • Does the file to be imported need to be prepended with an underscore? – snow Sep 18 '16 at 05:02
  • 1
    No, you should not. You simply write `@import "path/to/the/style"`. This, however, works differently on different implementations. Check @Farside's answer. – tftd Sep 18 '16 at 14:10
  • Bah! Was tripped up b/c Normalize's package name is `normalize.css` and I kept using `normalize/normalize`. +1 to @Nick! Though you only need `node_modules/normalize.css` since the package's `main` is `normalize.css`. You can also leave off the `node_modules` if you configure your `includePaths` with `node-sass`. – Curtis Blackwell Jan 10 '17 at 00:05
  • This is the only working solution that correctly applies to Vendor CSS files – Gerard Simpson Apr 13 '17 at 01:55
  • 1
    This should be the answer! It worked for me for cascading normalize with my .scss file: `@import url(~normalize.css/normalize.css);` – Jed Nov 12 '18 at 17:50
  • Problem here is that imported .css files in the resulting compiled/minified .css are put at the top, ignoring the right order. Any way to keep where they are? – Fred K Feb 28 '21 at 10:40
  • You should probably open a new question where you state what version of scss you are using (the darts one, the nodejs one or the ruby one) as well as if you're using webpack and minfiers (and which ones). If you're using webpack with a minifier then perhaps you need to configure the minfier settings not to optimise the import order. But again - open a new question :) – tftd Feb 28 '21 at 15:23
290

This was implemented and merged starting from version 3.2 (pull #754 merged on 2 Jan 2015 for libsass, issues originaly were defined here: sass#193 #556, libsass#318).

To cut the long story short, the syntax in next:

  1. to import (include) the raw CSS-file

    the syntax is **without `.css`** extension at the end (results in actual read of partial `s[ac]ss|css` and include of it inline to SCSS/SASS):

    @import "path/to/file";

  2. to import the CSS-file in a traditional way

    syntax goes in traditional way, **with `.css` extension** at the end (results to `@import url("path/to/file.css");` in your compiled CSS):

    @import "path/to/file.css";

And it is damn good: this syntax is elegant and laconic, plus backward compatible! It works excellently with libsass and node-sass.

__

To avoid further speculations in comments, writing this explicitly: Ruby based Sass still has this feature unimplemented after 7 years of discussions. By the time of writing this answer, it's promised that in 4.0 there will be a simple way to accomplish this, probably with the help of @use. It seems there will be an implementation very soon, the new "planned" "Proposal Accepted" tag was assigned for the issue #556 and the new @use feature.

UPD: on 26 October 2020 lib-sass was deprecated, therefore issue #556 was immediately closed.

__

answer might be updated, as soon as something changes.

Farside
  • 9,923
  • 4
  • 47
  • 60
  • 4
    just to clarify, importing the css as sass worked like this for me: @import url("path/to/file-without-css-extension"); – Craig Wayne Apr 28 '16 at 06:15
  • 1
    This doesn't actually work in the ruby-based version of sass. For example, the command: sass myFile.scss:output.css fails with a css import, but works when you change the .css file's extension to .scss. Run with the latest version as of the writing of this comment: 3.4.22 / Selective Steve. This also affects any task runners using the ruby version, like grunt-contrib-sass. – ansorensen Jun 21 '16 at 23:14
  • @ansorensen, I think there's confusion from your side. What do you mean by *"works when you change the .css file's extension to .scss"*? The whole idea was exactly about regular **CSS files**, and two ways of working with them (don't confuse with importing SCSS). Please read one more time the question and the answer. – Farside Jun 21 '16 at 23:44
  • 1
    @Farside No confusion. Import 'path/to/file' syntax doesn't work in the latest version of the sass gem in Ruby. When I run sass with an import, the import works successfully when the file at the path imported has an .scss extension and fails when the file has a .css. The question asks for an import of css into scss, and you provide an answer for lib-sass & node-sass. I'm commenting that this functionality is not in the ruby-based versions of sass. – ansorensen Jun 22 '16 at 23:44
  • It was the phrase 'works excellently with libsass and node-sass' that was ambiguous. Does it work with all sass, but you only tested it in libsass? Or was this an libsass-only feature? So I tested it with the Ruby version. – ansorensen Jun 22 '16 at 23:56
  • 1
    @ansorensen, omg, so many text from you... I was explicit, and don't confuse anyone. `Node-sass` is a Node.js library **LibSass** (the **C version** of Sass). Not a single mention that `libsass` or `node-sass` is Ruby based, not a single mention about RUBY version only in the original question. Please, read carefully, before writing 3 comments in a row next time. I have all the references: as per [issue#193](https://github.com/sass/sass/issues/193) it's still not implemented after 5 years of discussion for Ruby version, they promise this functionality only when **ver. 4.0** will be available. – Farside Jun 28 '16 at 14:47
  • Might I suggest adding something about importing an scss file works the same, sass finds the file. Imo, the best benefit to importing scss over css is that it's easy to bar an extension from upload. – Regular Jo Dec 03 '17 at 17:57
  • If the file is something like `file.min.css`, leaving off the `.css` extension didn't work for me. – mbomb007 Nov 27 '18 at 22:50
277

Looks like this is unimplemented, as of the time of this writing:

https://github.com/sass/sass/issues/193

For libsass (C/C++ implementation), import works for *.css the same way as for *.scss files - just omit the extension:

@import "path/to/file";

This will import path/to/file.css.

See this answer for further details.

See this answer for Ruby implementation (sass gem)

DaveAlden
  • 30,083
  • 11
  • 93
  • 155
Stephen Fuhry
  • 12,624
  • 6
  • 56
  • 55
  • 26
    @kleinfreund not true with Sass 3.3.1. The `@import` statement is not changed at all and appears in the resulting CSS file, Sass doesn't include the referenced CSS file like @GSto is asking. [It looks like it will be implemented in Sass 3.4 or 4.0](https://github.com/nex3/sass/issues/556#issuecomment-32367083) – fregante May 17 '14 at 16:58
  • 1
    If you're using Gulp or Grunt, just use a different tool to import your CSS files, it's easier and it works **now**. I use [gulp-import-css](https://www.npmjs.org/package/gulp-import-css), I'm not sure what's the Grunt equivalent. – fregante May 18 '14 at 02:32
  • 3
    It works with `libsass` at least. See the answer http://stackoverflow.com/questions/7111610/import-regular-css-file-in-scss-file/30279590#30279590 and PR https://github.com/sass/libsass/pull/754 – IVN Oct 05 '16 at 09:05
  • _"Import works for `*.css` the same way as for `*.css` files"_ is a tautology. You meant for one of those to be `*.scss`, right? – underscore_d Mar 04 '18 at 15:16
  • 1
    Starting in v3.5.3, libsass warns that this is non-standard behavior and should not be relied upon. (Instead "Use a custom importer to maintain this behaviour.") https://github.com/sass/libsass/releases/tag/3.5.3 – jacobq May 18 '18 at 21:56
  • Hi guys, simplest way is to rename your CSS file to SCSS !!! So you can use @import 'MyCSSImportFile'; in your main.scss AND benefit from inlining/merging of your SCSS + your CSS – djibe Dec 28 '18 at 12:13
  • it looks like libsass is deprecated :x – Fuseteam Sep 01 '20 at 13:55
  • tested on windows, dart 1.63.4 (not dartjs). Works if added at the _end_ of a `Sass` master file after all `@use`, in the resulting css `@import` appears at the _start_ of the file. – theking2 Jun 14 '23 at 13:12
264

You must prepend an underscore to the css file to be included, and switch its extension to scss (ex: _yourfile.scss). Then you just have to call it this way:

@import "yourfile";

And it will include the contents of the file, instead of using the CSS standard @import directive.

Rubens Mariuzzo
  • 28,358
  • 27
  • 121
  • 148
David Morales
  • 17,816
  • 12
  • 77
  • 105
  • Thank you! This works, but I found that I didn't need to pre-pend an underscore in order for it to work. Is there something that I'm missing with the underscore? – Tyson Phalp Nov 05 '12 at 20:13
  • 74
    The underscore is to prevent it from being compiled as a separate file. – Jonah Feb 25 '13 at 22:23
  • 4
    In case anyone's wondering, this works because Sass' SCSS syntax is a superset of CSS3. That's also why the semicolon is needed. – Jacob Wan Sep 15 '13 at 19:18
  • 49
    You can't change extension of some vendor CSS file for example. – Slava Fomin II Apr 09 '14 at 18:58
  • 7
    If it's on your computer/server you can! And there is also symbolic links if you wish not to. – ste Sep 15 '14 at 22:04
  • I'm on Sass 3.4.10 and didn't need an underscore, FYI. – Bad Request Feb 19 '15 at 17:20
  • @DanOchiana How exactly is this not the cleanest solution? The css-importer doesn't work anymore. This eliminates the need for linking your CSS in HTML without losing the effect. Keep in mind that order still applies in your source file structure (ie: gulpfile.js/karma.config.js). +1 from me. Thanks, C§ – CSS Aug 20 '15 at 21:08
  • @SlavaFominII You can if you can control your buildscripts. – peterh Mar 29 '17 at 11:53
  • For me, both the file name and the string name within the .scss file had to be identical (include underscore). It now works in the latest version of Chrome and IE Edge without console errors. – klewis May 15 '17 at 18:56
42

Good news everyone, Chris Eppstein created a compass plugin with inline css import functionality:

https://github.com/chriseppstein/sass-css-importer

Now, importing a CSS file is as easy as:

@import "CSS:library/some_css_file"
Rafal Pastuszak
  • 3,100
  • 2
  • 29
  • 31
  • 3
    Fails due to using deprecated starting point. "What is, but can never be..." I'm sure it was great when it first came out, but it needs an update to function again, or you must install deprecated plugins. Thanks, C§ – CSS Aug 20 '15 at 21:10
  • Works if including a .css extension to the file. For instance `@import '/fonts/Lato.css'`. Tested in Windows dart 1.63.4 – theking2 Jun 14 '23 at 13:15
18

If you have a .css file which you don't wish to modify, neither change its extension to .scss (e.g. this file is from a forked project you don't maintain), you can always create a symlink and then import it into your .scss.

Creates a symlink:

ln -s path/to/css/file.css path/to/sass/files/_file.scss


Imports symlink file into a target .scss:

@import "path/to/sass/files/file";


Your target output .css file is going to hold contents from imported symlink .scss file, not a CSS import rule (mentioned by @yaz with highest comment votes). And you don't have duplicated files with different extensions, what means any update made inside initial .css file immediately gets imported into your target output.

Symbolic link (also symlink or soft link) is a special type of file that contains a reference to another file in the form of an absolute or relative path and that affects pathname resolution.
http://en.wikipedia.org/wiki/Symbolic_link

Moshe Katz
  • 15,992
  • 7
  • 69
  • 116
Nik Sumeiko
  • 8,263
  • 8
  • 50
  • 53
  • 10
    Adding a symlink is not a very portable solution (i.e. multiple developers or build systems) – LocalPCGuy Dec 04 '14 at 19:06
  • @LocalPCGuy it is, when both files (`.css` and created symlink) are available to everyone via a shared repository, for example. – Nik Sumeiko Dec 05 '14 at 07:20
  • I just did this and was gonna answer about sym links on this thread, but glad it's already here! It's true that this need is rare, but my situation involved not wanting to modify the CSS file at all (because it was a bower file), so building a symlink and importing that worked perfectly. – Aaron Krauss Jul 17 '15 at 15:41
  • 2
    For **Windows** users, the same functionality would have a different syntax `mklink /H `, and it's called *hard link* @mrsafraz. – Farside Mar 22 '16 at 22:49
5

You can use a third-party importer to customise @import semantics.

node-sass-import-once, which works with node-sass (for Node.js) can inline import CSS files.

Example of direct usage:

var sass = require('node-sass');,
    importOnce = require('node-sass-import-once');

sass.render({
  file: "input.scss",
  importer: importOnce,
  importOnce: {
    css: true,
  }
});

Example grunt-sass config:

var importOnce = require("node-sass-import-once");
grunt.loadNpmTasks("grunt-sass");

grunt.initConfig({
  sass: {
    options: {
      sourceMap: true,
      importer: importOnce
    },
    dev: {
      files: {
        "dist/style.css": "scss/**/*.scss"
      }
    }
  });

Note that node-sass-import-once cannot currently import Sass partials without an explicit leading underscore. For example with the file partials/_partial.scss:

  • @import partials/_partial.scss succeeds
  • @import * partials/partial.scss fails

In general, be aware that a custom importer could change any import semantics. Read the docs before you start using it.

joews
  • 29,767
  • 10
  • 79
  • 91
4

If I am correct css is compatible with scss so you can change the extension of a css to scss and it should continue to work. Once you change the extension you can import it and it will be included in the file.

If you don't do that sass will use the css @import which is something you don't want.

Pickels
  • 33,902
  • 26
  • 118
  • 178
  • 16
    unfortunately sometimes the imported css files are out of your control, as in a library which packages some static assets. – Eric Drechsel Nov 26 '11 at 00:09
3

to Import css file in to scss simply use the this: @import "src/your_file_path"; without using extension .css at the end

2

I figured out an elegant, Rails-like way to do it. First, rename your .scss file to .scss.erb, then use syntax like this (example for highlight_js-rails4 gem CSS asset):

@import "<%= asset_path("highlight_js/github") %>";

Why you can't host the file directly via SCSS:

Doing an @import in SCSS works fine for CSS files as long as you explicitly use the full path one way or another. In development mode, rails s serves assets without compiling them, so a path like this works...

@import "highlight_js/github.css";

...because the hosted path is literally /assets/highlight_js/github.css. If you right-click on the page and "view source", then click on the link for the stylesheet with the above @import, you'll see a line in there that looks like:

@import url(highlight_js/github.css);

The SCSS engine translates "highlight_js/github.css" to url(highlight_js/github.css). This will work swimmingly until you decide to try running it in production where assets are precompiled have a hash injected into the file name. The SCSS file will still resolve to a static /assets/highlight_js/github.css that was not precompiled and doesn't exist in production.

How this solution works:

Firstly, by moving the .scss file to .scss.erb, we have effectively turned the SCSS into a template for Rails. Now, whenever we use <%= ... %> template tags, the Rails template processor will replace these snippets with the output of the code (just like any other template).

Stating asset_path("highlight_js/github") in the .scss.erb file does two things:

  1. Triggers the rake assets:precompile task to precompile the appropriate CSS file.
  2. Generates a URL that appropriately reflects the asset regardless of the Rails environment.

This also means that the SCSS engine isn't even parsing the CSS file; it's just hosting a link to it! So there's no hokey monkey patches or gross workarounds. We're serving a CSS asset via SCSS as intended, and using a URL to said CSS asset as Rails intended. Sweet!

Synthead
  • 2,162
  • 5
  • 22
  • 25
  • To me the solution seems a bit shady and sounds more like a hack. But it's a good job on investigation! – Farside Jul 28 '16 at 12:11
1

Simple workaround:

All, or nearly all css file can be also interpreted as if it would be scss. It also enables to import them inside a block. Rename the css to scss, and import it so.

In my actual configuration I do the following:

First I copy the .css file into a temporary one, this time with .scss extension. Grunt example config:

copy: {
    dev: {
        files: [
            {
                src: "node_modules/some_module/some_precompiled.css",
                dest: "target/resources/some_module_styles.scss"
            }
        ]
    }
}

Then you can import the .scss file from your parent scss (in my example, it is even imported into a block):

my-selector {
  @import "target/resources/some_module_styles.scss";
  ...other rules...
}

Note: this could be dangerous, because it will effectively result that the css will be parsed multiple times. Check your original css for that it contains any scss-interpretable artifact (it is improbable, but if it happen, the result will be hard to debug and dangerous).

peterh
  • 11,875
  • 18
  • 85
  • 108
1

To import a regular CSS file into Sass:

Official Sass Documentation: Import CSS into Sass

enter image description here

David Asbill
  • 128
  • 5
-3

It is now possible using:

@import 'CSS:directory/filename.css';
Shlomi Schwartz
  • 8,693
  • 29
  • 109
  • 186
  • 4
    only if gem `sass-css-importer` is installed, sass is called with switch `-r sass-css-importer` and `.css` is omitted from the file path – Bernhard Döbler Sep 13 '14 at 17:58
-5

I can confirm this works:

class CSSImporter < Sass::Importers::Filesystem
  def extensions
    super.merge('css' => :scss)
  end
end

view_context = ActionView::Base.new
css = Sass::Engine.new(
  template,
  syntax:     :scss,
  cache:      false,
  load_paths: Rails.application.assets.paths,
  read_cache: false,
  filesystem_importer: CSSImporter # Relevant option,

  sprockets:  {
    context:     view_context,
    environment: Rails.application.assets
  }
).render

Credit to Chriss Epstein: https://github.com/sass/sass/issues/193

Macario
  • 2,214
  • 2
  • 22
  • 40
-9

Simple.

@import "path/to/file.css";

Adam Stacoviak
  • 318
  • 2
  • 7
  • 8
    I've tried this, but it wont pull the contents of the file into that one when compressing it, it will just keep the @import line. – GSto Aug 19 '11 at 15:01
  • 1
    Lowest scored answer, but ironically, this seems to be the right way, now. Including the suffix is the right thing to do. – Wyck Nov 23 '18 at 03:25