mirror of
https://github.com/danog/sass-site.git
synced 2024-11-27 04:24:50 +01:00
622 lines
18 KiB
Plaintext
622 lines
18 KiB
Plaintext
---
|
|
title: "@import"
|
|
table_of_contents: true
|
|
introduction: >
|
|
Sass extends CSS's [`@import`
|
|
rule](https://developer.mozilla.org/en-US/docs/Web/CSS/@import) with the
|
|
ability to import Sass and CSS stylesheets, providing access to
|
|
[mixins](/documentation/at-rules/mixin),
|
|
[functions](/documentation/at-rules/function), and
|
|
[variables](/documentation/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.
|
|
---
|
|
|
|
{% markdown %}
|
|
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]: /documentation/syntax#the-indented-syntax
|
|
{% endmarkdown %}
|
|
|
|
{% headsUp %}
|
|
The Sass team discourages the continued use of the `@import` rule. Sass will
|
|
[gradually phase it out][] over the next few years, and eventually remove it
|
|
from the language entirely. Prefer the [`@use` rule][] instead. (Note that
|
|
only Dart Sass currently supports `@use`. Users of other implementations must
|
|
use the `@import` rule instead.)
|
|
|
|
[gradually phase it out]: https://github.com/sass/sass/blob/master/accepted/module-system.md#timeline
|
|
[`@use` rule]: /documentation/at-rules/use
|
|
|
|
<h4>{{ "What's Wrong With `@import`?" | markdown }}</h4>
|
|
|
|
The `@import` rule has a number of serious issues:
|
|
|
|
* `@import` makes all variables, mixins, and functions globally accessible.
|
|
This makes it very difficult for people (or tools) to tell where anything is
|
|
defined.
|
|
|
|
* Because everything's global, libraries must add a prefix to all their
|
|
members to avoid naming collisions.
|
|
|
|
* [`@extend` rules][] are also global, which makes it difficult to predict
|
|
which style rules will be extended.
|
|
|
|
[`@extend` rules]: extend
|
|
|
|
* Each stylesheet is executed and its CSS emitted *every time* it's
|
|
`@import`ed, which increases compilation time and produces bloated output.
|
|
|
|
* There was no way to define private members or placeholder selectors that
|
|
were inaccessible to downstream stylesheets.
|
|
|
|
The new module system and the `@use` rule address all these problems.
|
|
|
|
<h4>{{ 'How Do I Migrate?' | markdown }}</h4>
|
|
|
|
We've written a [migration tool][] that automatically converts most
|
|
`@import`-based code to `@use`-based code in a flash. Just point it at your
|
|
entrypoints and let it run!
|
|
|
|
[migration tool]: /documentation/cli/migrator
|
|
{% endheadsUp %}
|
|
|
|
{% codeExample 'import' %}
|
|
// 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;
|
|
}
|
|
{% endcodeExample %}
|
|
|
|
{% markdown %}
|
|
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.
|
|
|
|
[mixins]: /documentation/at-rules/mixin
|
|
[functions]: /documentation/at-rules/function
|
|
[variables]: /documentation/variables
|
|
|
|
{% headsUp %}
|
|
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.
|
|
{% endheadsUp %}
|
|
|
|
## 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`.
|
|
|
|
{% headsUp %}
|
|
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.
|
|
{% endheadsUp %}
|
|
|
|
### 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.
|
|
|
|
{% funFact %}
|
|
Unlike some other languages, Sass doesn't require that you use `./` for
|
|
relative imports. Relative imports are always available.
|
|
{% endfunFact %}
|
|
|
|
### 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
|
|
|
|
{% compatibility 'dart: true', 'libsass: "3.6.0"', 'ruby: "3.6.0"' %}{% endcompatibility %}
|
|
|
|
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.
|
|
{% endmarkdown %}
|
|
|
|
{% codeExample 'index-files' %}
|
|
// 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;
|
|
}
|
|
{% endcodeExample %}
|
|
|
|
{% markdown %}
|
|
### 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]: /documentation/style-rules
|
|
[plain CSS at-rules]: /documentation/at-rules/css
|
|
[mixins]: /documentation/at-rules/mixin
|
|
[functions]: /documentation/at-rules/function
|
|
[variables]: /documentation/variables
|
|
{% endmarkdown %}
|
|
|
|
{% codeExample 'nesting' %}
|
|
// _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.sass
|
|
.theme-sample
|
|
@import theme
|
|
===
|
|
.theme-sample pre, .theme-sample code {
|
|
font-family: 'Source Code Pro', Helvetica, Arial;
|
|
border-radius: 4px;
|
|
}
|
|
{% endcodeExample %}
|
|
|
|
{% funFact %}
|
|
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]: /documentation/at-rules/mixin
|
|
{% endfunFact %}
|
|
|
|
{% headsUp false %}
|
|
{% markdown %}
|
|
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]: /documentation/style-rules/parent-selector
|
|
{% endmarkdown %}
|
|
|
|
{% codeExample 'parent-selector' %}
|
|
// _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;
|
|
}
|
|
{% endcodeExample %}
|
|
{% endheadsUp %}
|
|
|
|
{% markdown %}
|
|
## Importing CSS
|
|
|
|
{% compatibility 'dart: "1.11.0"', 'libsass: "partial"', 'ruby: false' %}
|
|
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.
|
|
{% endcompatibility %}
|
|
|
|
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
|
|
{% endmarkdown %}
|
|
|
|
{% codeExample 'import-css' %}
|
|
// 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;
|
|
}
|
|
{% endcodeExample %}
|
|
|
|
{% markdown %}
|
|
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]: /documentation/at-rules/extend
|
|
|
|
## Plain CSS `@import`s
|
|
|
|
{% compatibility 'dart: true', 'libsass: "partial"', 'ruby: true' %}
|
|
By default, LibSass handles plain CSS imports correctly. However, any
|
|
[custom importers][] will incorrectly apply to plain-CSS `@import` rules,
|
|
making it possible for those rules to load Sass files.
|
|
|
|
[custom importers]: /documentation/js-api/interfaces/LegacySharedOptions#importer
|
|
{% endcompatibility %}
|
|
|
|
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.
|
|
{% endmarkdown %}
|
|
|
|
{% codeExample 'plain-css-imports' %}
|
|
@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)
|
|
{% endcodeExample %}
|
|
|
|
{% markdown %}
|
|
### 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]: /documentation/interpolation
|
|
[mixins]: /documentation/at-rules/mixin
|
|
[functions]: /documentation/at-rules/function
|
|
[variables]: /documentation/variables
|
|
{% endmarkdown %}
|
|
|
|
{% codeExample 'interpolation' %}
|
|
@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")
|
|
{% endcodeExample %}
|
|
|
|
{% markdown %}
|
|
## Import and Modules
|
|
|
|
{% render 'doc_snippets/module-system-status' %}
|
|
|
|
Sass's [module system][] integrates seamlessly with `@import`, whether you're
|
|
importing a file that contains `@use` rules or loading a file that contains
|
|
imports as a module. We want to make the transition from `@import` to `@use`
|
|
as smooth as possible.
|
|
|
|
[module system]: /documentation/at-rules/use
|
|
|
|
### Importing a Module-System File
|
|
|
|
When you import a file that contains `@use` rules, the importing file has
|
|
access to all members (even private members) defined directly in that file,
|
|
but *not* any members from modules that file has loaded. However, if that file
|
|
contains [`@forward` rules][], the importing file will have access to
|
|
forwarded members. This means that you can import a library that was written
|
|
to be used with the module system.
|
|
|
|
[`@forward` rules]: /documentation/at-rules/forward
|
|
|
|
{% headsUp %}
|
|
When a file with `@use` rules is imported, all the CSS transitively loaded
|
|
by those is included in the resulting stylesheet, even if it's already been
|
|
included by another import. If you're not careful, this can result in
|
|
bloated CSS output!
|
|
{% endheadsUp %}
|
|
|
|
#### Import-Only Files
|
|
|
|
An API that makes sense for `@use` might not make sense for `@import`. For
|
|
example, `@use` adds a namespace to all members by default so you can safely
|
|
use short names, but `@import` doesn't so you might need something longer. If
|
|
you're a library author, you may be concerned that if you update your library
|
|
to use the new module system, your existing `@import`-based users will break.
|
|
|
|
To make this easier, Sass also supports *import-only files*. If you name a
|
|
file `<name>.import.scss`, it will only be loaded for imports, not for
|
|
`@use`s. This way, you can retain compatibility for `@import` users while
|
|
still providing a nice API for users of the new module system.
|
|
{% endmarkdown %}
|
|
|
|
{% codeExample 'import-only-files', false %}
|
|
// _reset.scss
|
|
|
|
// Module system users write `@include reset.list()`.
|
|
@mixin list() {
|
|
ul {
|
|
margin: 0;
|
|
padding: 0;
|
|
list-style: none;
|
|
}
|
|
}
|
|
---
|
|
// _reset.import.scss
|
|
|
|
// Legacy import users can keep writing `@include reset-list()`.
|
|
@forward "reset" as reset-*;
|
|
===
|
|
// _reset.sass
|
|
|
|
// Module system users write `@include reset.list()`.
|
|
@mixin list()
|
|
ul
|
|
margin: 0
|
|
padding: 0
|
|
list-style: none
|
|
---
|
|
// _reset.import.sass
|
|
|
|
// Legacy import users can keep writing `@include reset-list()`.
|
|
@forward "reset" as reset-*
|
|
{% endcodeExample %}
|
|
|
|
{% markdown %}
|
|
#### Configuring Modules Through Imports
|
|
|
|
{% compatibility 'dart: "1.24.0"', 'libsass: false', 'ruby: false' %}{% endcompatibility %}
|
|
|
|
You can [configure modules][] that are loaded through an `@import` by defining
|
|
global variables prior the `@import` that first loads that module.
|
|
|
|
[configure modules]: /documentation/at-rules/use#configuration
|
|
{% endmarkdown %}
|
|
|
|
{% codeExample 'configuring-modules' %}
|
|
// _library.scss
|
|
$color: blue !default;
|
|
|
|
a {
|
|
color: $color;
|
|
}
|
|
---
|
|
// _library.import.scss
|
|
@forward 'library' as lib-*;
|
|
---
|
|
// style.sass
|
|
$lib-color: green;
|
|
@import "library";
|
|
===
|
|
$color: blue !default
|
|
|
|
a
|
|
color: $color
|
|
---
|
|
// _library.import.sass
|
|
@forward 'library' as lib-*
|
|
---
|
|
// style.sass
|
|
$lib-color: green
|
|
@import "library"
|
|
===
|
|
a {
|
|
color: green;
|
|
}
|
|
{% endcodeExample %}
|
|
|
|
{% headsUp %}
|
|
Modules are only loaded once, so if you change the configuration after you
|
|
`@import` a module for the first time (even indirectly), the change will be
|
|
ignored if you `@import` the module again.
|
|
{% endheadsUp %}
|
|
|
|
{% markdown %}
|
|
### Loading a Module That Contains Imports
|
|
|
|
When you use `@use` (or `@forward`) load a module that uses `@import`, that
|
|
module will contain all the public members defined by the stylesheet you load
|
|
*and* everything that stylesheet transitively imports. In other words,
|
|
everything that's imported is treated as though it were written in one big
|
|
stylesheet.
|
|
|
|
This makes it easy to convert start using `@use` in a stylesheet even before
|
|
all the libraries you depend on have converted to the new module system. Be
|
|
aware, though, that if they do convert their APIs may well change!
|
|
{% endmarkdown %}
|