sass-site/source/documentation/at-rules/import.html.md.erb
2019-01-09 14:36:31 -08:00

407 lines
11 KiB
Plaintext

---
title: "@import"
table_of_contents: true
---
Sass extends CSS's [`@import` rule][] with the ability to import Sass and CSS
stylesheets, providing access to [mixins][], [functions][], and [variables][]
and combining multiple stylesheets' CSS together. Unlike plain CSS imports,
which require the browser to make multiple HTTP requests as it renders your
page, Sass imports are handled entirely during compilation.
[`@import` rule]: https://developer.mozilla.org/en-US/docs/Web/CSS/@import
[mixins]: mixin
[functions]: function
[variables]: ../variables
Sass imports have the same syntax as CSS imports, except that they allow
multiple imports to be separated by commas rather than requiring each one to
have its own `@import`. Also, in the [indented syntax][], imported URLs aren't
required to have quotes.
[indented syntax]: ../syntax#the-indented-syntax
<% example do %>
// foundation/_code.scss
code {
padding: .25em;
line-height: 0;
}
---
// foundation/_lists.scss
ul, ol {
text-align: left;
& & {
padding: {
bottom: 0;
left: 0;
}
}
}
---
// style.scss
@import 'foundation/code', 'foundation/lists';
===
// foundation/_code.sass
code
padding: .25em
line-height: 0
---
// foundation/_lists.sass
ul, ol
text-align: left
& &
padding:
bottom: 0
left: 0
---
// style.sass
@import foundation/code, foundation/lists
===
code {
padding: .25em;
line-height: 0;
}
ul, ol {
text-align: left;
}
ul ul, ol ol {
padding-bottom: 0;
padding-left: 0;
}
<% end %>
When Sass imports a file, that file is evaluated as though its contents appeared
directly in place of the `@import`. Any [mixins][], [functions][], and
[variables][] from the imported file are made available, and all its CSS is
included at the exact point where the `@import` was written. What's more, any
mixins, functions, or variables that were defined before the `@import`
(including from other `@import`s) are available in the imported stylesheet.
<% heads_up do %>
If the same stylesheet is imported more than once, it will be evaluated again
each time. If it just defines functions and mixins, this usually isn't a big
deal, but if it contains style rules they'll be compiled to CSS more than
once.
<% end %>
## Finding the File
It wouldn't be any fun to write out absolute URLs for every stylesheet you
import, so Sass's algorithm for finding a file to import makes it a little
easier. For starters, you don't have to explicitly write out the extension of
the file you want to import; `@import "variables"` will automatically load
`variables.scss`, `variables.sass`, or `variables.css`.
<% heads_up do %>
To ensure that stylesheets work on every operating system, Sass imports files
by *URL*, not by *file path*. This means you need to use forward slashes, not
backslashes, even when you're on Windows.
<% end %>
### Load Paths
All Sass implementations allow users to provide *load paths*: paths on the
filesystem that Sass will look in when resolving imports. For example, if you
pass `node_modules/susy/sass` as a load path, you can use `@import "susy"` to
load `node_modules/susy/sass/susy.scss`.
Imports will always be resolved relative to the current file first, though. Load
paths will only be used if no relative file exists that matches the import. This
ensures that you can't accidentally mess up your relative imports when you add a
new library.
<% fun_fact do %>
Unlike some other languages, Sass doesn't require that you use `./` for
relative imports. Relative imports are always available.
<% end %>
### Partials
As a convention, Sass files that are only meant to be imported, not compiled on
their own, begin with `_` (as in `_code.scss`). These are called *partials*, and
they tell Sass tools not to try to compile those files on their own. You can
leave off the `_` when importing a partial.
### Index Files
<% impl_status dart: true, libsass: '3.5.0', ruby: '3.6.0' %>
If you write an `_index.scss` or `_index.sass` in a folder, when the folder
itself is imported that file will be loaded in its place.
<% example do %>
// foundation/_code.scss
code {
padding: .25em;
line-height: 0;
}
---
// foundation/_lists.scss
ul, ol {
text-align: left;
& & {
padding: {
bottom: 0;
left: 0;
}
}
}
---
// foundation/_index.scss
@import 'code', 'lists';
---
// style.scss
@import 'foundation';
===
// foundation/_code.sass
code
padding: .25em
line-height: 0
---
// foundation/_lists.sass
ul, ol
text-align: left
& &
padding:
bottom: 0
left: 0
---
// foundation/_index.sass
@import code, lists
---
// style.sass
@import foundation
===
code {
padding: .25em;
line-height: 0;
}
ul, ol {
text-align: left;
}
ul ul, ol ol {
padding-bottom: 0;
padding-left: 0;
}
<% end %>
### Custom Importers
All Sass implementations provide a way to define custom importers, which control
how `@import`s locate stylesheets:
* [Node Sass][] and [Dart Sass on npm][] provide an [`importer` option][] as
part of their JS API.
* [Dart Sass on pub][] provides an abstract [`Importer` class][] that can be
extended by a custom importer.
* [Ruby Sass][] provides an abstract [`Importers::Base` class][] that can be
extended by a custom importer.
[Node Sass]: https://npmjs.com/package/node-sass
[Dart Sass on npm]: https://npmjs.com/package/sass
[`importer` option]: https://github.com/sass/node-sass#importer--v200---experimental
[Dart Sass on pub]: https://pub.dartlang.org/packages/sass
[`Importer` class]: https://pub.dartlang.org/documentation/sass/latest/sass/Importer-class.html
[Ruby Sass]: /ruby-sass
[`Importers::Base` class]: https://www.rubydoc.info/gems/sass/Sass/Importers/Base
## Nesting
Imports are usually written at the top level of a stylesheet, but they don't
have to be. They can nested within [style rules][] or [plain CSS at-rules][] as
well. The imported CSS is nested in that context, which makes nested imports
useful for scoping a chunk of CSS to a particular element or media query. Note
that top-level [mixins][], [functions][], and [variables][] defined in the
nested import are still defined globally, though.
[style rules]: ../style-rules
[plain CSS at-rules]: css
<% example do %>
// _theme.scss
pre, code {
font-family: 'Source Code Pro', Helvetica, Arial;
border-radius: 4px;
}
---
// style.scss
.theme-sample {
@import "theme";
}
===
// _theme.sass
pre, code
font-family: 'Source Code Pro', Helvetica, Arial
border-radius: 4px
---
// style.sas
.theme-sample
@import theme
===
.theme-sample pre, .theme-sample code {
font-family: 'Source Code Pro', Helvetica, Arial;
border-radius: 4px;
}
<% end %>
<% fun_fact do %>
Nested imports are very useful for scoping third-party stylesheets, but if
you're the author of the stylesheet you're importing, it's usually a better
idea to write your styles in a [mixin][] and include that mixin in the nested
context. A mixin can be used in more flexible ways, and it's clearer when
looking at the imported stylesheet how it's intended to be used.
[mixin]: mixin
<% end %>
<% heads_up do %>
The CSS in nested imports is evaluated like a mixin, which means that any
[parent selectors][] will refer to the selector in which the stylesheet is
nested.
[parent selectors]: ../style-rules/parent-selector
<% example do %>
// _theme.scss
ul li {
$padding: 16px;
padding-left: $padding;
[dir=rtl] & {
padding: {
left: 0;
right: $padding;
}
}
}
---
// style.scss
.theme-sample {
@import "theme";
}
===
// _theme.sass
ul li
$padding: 16px
padding-left: $padding
[dir=rtl] &
padding:
left: 0
right: $padding
---
// style.sass
.theme-sample
@import theme
===
.theme-sample ul li {
padding-left: 16px;
}
[dir=rtl] .theme-sample ul li {
padding-left: 0;
padding-right: 16px;
}
<% end %>
<% end %>
## Importing CSS
<% impl_status dart: '1.11.0', libsass: false, ruby: false do %>
LibSass supports importing files with the extension `.css`, but contrary to
the specification they're treated as SCSS files rather than being parsed as
CSS. This behavior has been deprecated, and an update is in the works to
support the behavior described below.
<% end %>
In addition to importing `.sass` and `.scss` files, Sass can import plain old
`.css` files. The only rule is that the import *must not* explicitly include the
`.css` extension, because that's used to indicate a [plain CSS `@import`][].
[plain CSS `@import`]: #plain-css-imports
<% example do %>
// code.css
code {
padding: .25em;
line-height: 0;
}
---
// style.scss
@import 'code';
===
// code.css
code {
padding: .25em;
line-height: 0;
}
---
// style.sass
@import code
===
code {
padding: .25em;
line-height: 0;
}
<% end %>
CSS files imported by Sass don't allow any special Sass features. In order to
make sure authors don't accidentally write Sass in their CSS, all Sass features
that aren't also valid CSS will produce errors. Otherwise, the CSS will be
rendered as-is. It can even be [extended][]!
[extended]: extend
## Plain CSS `@import`s
Because `@import` is also defined in CSS, Sass needs a way of compiling plain
CSS `@import`s without trying to import the files at compile time. To accomplish
this, and to ensure SCSS is as much of a superset of CSS as possible, Sass will
compile any `@import`s with the following characteristics to plain CSS imports:
* Imports where the URL ends with `.css`.
* Imports where the URL begins `http://` or `https://`.
* Imports where the URL is written as a `url()`.
* Imports that have media queries.
<% example do %>
@import "theme.css";
@import "http://fonts.googleapis.com/css?family=Droid+Sans";
@import url(theme);
@import "landscape" screen and (orientation: landscape);
===
@import "theme.css"
@import "http://fonts.googleapis.com/css?family=Droid+Sans"
@import url(theme)
@import "landscape" screen and (orientation: landscape)
<% end %>
### Interpolation
Although Sass imports can't use [interpolation][] (to make sure it's always
possible to tell where [mixins][], [functions][], and [variables][] come from),
plain CSS imports can. This makes it possible to dynamically generate imports,
for example based on mixin parameters.
[interpolation]: ../interpolation
<% example do %>
@mixin google-font($family) {
@import url("http://fonts.googleapis.com/css?family=#{$family}");
}
@include google-font("Droid Sans");
===
@mixin google-font($family)
@import url("http://fonts.googleapis.com/css?family=#{$family}")
@include google-font("Droid Sans")
<% end %>