`@import`
Sass 擴展了 CSS 的 `@import` 規則,使其能夠匯入 Sass 和 CSS 樣式表,提供存取 Mixin、函式 和 變數 的能力,並將多個樣式表的 CSS 合併在一起。與純 CSS 匯入不同(純 CSS 匯入需要瀏覽器在渲染頁面時發出多個 HTTP 請求),Sass 匯入完全在編譯期間處理。
Sass 匯入的語法與 CSS 匯入相同,除了它們允許多個匯入以逗號分隔,而不是要求每個匯入都有自己的 `@import`。此外,在縮排語法中,匯入的 URL 不需要引號。
⚠️ 注意!
Sass 團隊不鼓勵繼續使用 `@import` 規則。Sass 將在未來幾年逐步淘汰它,最終將其從語言中完全移除。建議改用 `@use` 規則。(請注意,目前只有 Dart Sass 支援 `@use`。其他實作的使用者必須改用 `@import` 規則。)
`@import` 的問題是什麼?
`@import` 規則有一些嚴重的問題:
-
`@import` 使所有變數、Mixin 和函式都可全域存取。這使得人們(或工具)很難判斷任何東西的定義位置。
-
由於所有東西都是全域的,程式庫必須為所有成員添加前綴,以避免命名衝突。
-
@extend
規則 也是全域的,這使得難以預測哪些樣式規則將被繼承。 -
每個樣式表都會在每次被
@import
時執行並輸出其 CSS,這會增加編譯時間並產生過於臃腫的輸出。 -
沒有辦法定義私有成員或佔位符選擇器,讓下游樣式表無法存取。
新的模組系統和 @use
規則解決了所有這些問題。
如何遷移?
我們編寫了一個 遷移工具,可以快速自動將大多數基於 @import
的程式碼轉換為基於 @use
的程式碼。只需將其指向您的入口點,然後讓它執行即可!
SCSS 語法
// 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';
Sass 語法
// 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
CSS 輸出
code {
padding: .25em;
line-height: 0;
}
ul, ol {
text-align: left;
}
ul ul, ol ol {
padding-bottom: 0;
padding-left: 0;
}
當 Sass 導入檔案時,該檔案的評估方式如同其內容直接出現在 @import
的位置。導入檔案中的任何 Mixin、函式 和 變數 都將可用,並且其所有 CSS 都包含在 @import
編寫的確切位置。此外,在 @import
之前定義的任何 Mixin、函式或變數(包括來自其他 @import
的)都可在導入的樣式表中使用。
⚠️ 注意!
如果同一樣式表被導入多次,則每次都會重新評估。如果它只定義函式和 Mixin,這通常不是什麼大問題,但如果它包含樣式規則,它們將被多次編譯成 CSS。
尋找檔案尋找檔案 永久連結
為每個導入的樣式表寫出絕對網址並不好玩,因此 Sass 的尋找導入檔案的演算法使其更容易一些。首先,您不必明確寫出要導入的檔案的副檔名;@import "variables"
將自動載入 variables.scss
、variables.sass
或 variables.css
。
⚠️ 注意!
為了確保樣式表在每個作業系統上都能正常運作,Sass 透過 *URL* 而不是 *檔案路徑* 導入檔案。這表示即使在 Windows 上,您也需要使用正斜線,而不是反斜線。
載入路徑載入路徑 永久連結
所有 Sass 實作都允許使用者提供 *載入路徑*:Sass 在解析導入時將在其上尋找的檔案系統路徑。例如,如果您將 node_modules/susy/sass
作為載入路徑傳遞,則可以使用 @import "susy"
載入 node_modules/susy/sass/susy.scss
。
不過,導入將始終先相對於目前檔案解析。只有在沒有符合導入的相對檔案存在時,才會使用載入路徑。這可確保在新增程式庫時不會意外弄亂相對導入。
💡 小知識
與其他一些語言不同,Sass 不需要您對相對導入使用 ./
。相對導入始終可用。
局部檔案局部檔案 永久連結
按照慣例,僅供導入而不自行編譯的 Sass 檔案會以 _
開頭(例如 _code.scss
)。這些檔案稱為「*局部檔案*」,它們會告知 Sass 工具不要自行編譯這些檔案。導入局部檔案時可以省略 _
。
索引檔案索引檔案永久連結
- Dart Sass
- ✓
- LibSass
- 自 3.6.0 版起
- Ruby Sass
- 自 3.6.0 版起
如果您在資料夾中撰寫 _index.scss
或 _index.sass
檔案,則在導入該資料夾本身時,會載入該檔案。
SCSS 語法
// 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';
Sass 語法
// 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
CSS 輸出
code {
padding: .25em;
line-height: 0;
}
ul, ol {
text-align: left;
}
ul ul, ol ol {
padding-bottom: 0;
padding-left: 0;
}
自訂導入器自訂導入器永久連結
所有 Sass 實作都提供定義自訂導入器的方法,用於控制 @import
如何定位樣式表。
-
Node Sass 和 npm 上的 Dart Sass 在其 JS API 中提供
importer
選項。 -
pub 上的 Dart Sass 提供一個抽象的
Importer
類別,可以由自訂導入器繼承。 -
Ruby Sass 提供一個抽象的
Importers::Base
類別,可以由自訂導入器繼承。
巢狀巢狀永久連結
導入通常寫在樣式表的頂層,但並非必須如此。它們也可以巢狀在樣式規則或純 CSS at 規則內。導入的 CSS 會巢狀在該環境中,這使得巢狀導入適用於將一部分 CSS 的範圍限定於特定元素或媒體查詢。在巢狀導入中定義的頂層 mixin、函式 和 變數 僅在巢狀環境中可用。
SCSS 語法
// _theme.scss
pre, code {
font-family: 'Source Code Pro', Helvetica, Arial;
border-radius: 4px;
}
// style.scss
.theme-sample {
@import "theme";
}
Sass 語法
// _theme.sass
pre, code
font-family: 'Source Code Pro', Helvetica, Arial
border-radius: 4px
// style.sass
.theme-sample
@import theme
CSS 輸出
.theme-sample pre, .theme-sample code {
font-family: 'Source Code Pro', Helvetica, Arial;
border-radius: 4px;
}
💡 小知識
巢狀導入對於限定第三方樣式表的範圍非常有用,但如果您是所導入樣式表的作者,通常更好的做法是在 mixin 中撰寫您的樣式,並將該 mixin 包含在巢狀環境中。mixin 可以更彈性地使用,而且在查看導入的樣式表時,可以更清楚地了解其預期用途。
⚠️ 注意!
巢狀導入中的 CSS 的評估方式類似於 mixin,這表示任何 父選擇器 都將參考樣式表巢狀所在的選擇器。
SCSS 語法
// _theme.scss
ul li {
$padding: 16px;
padding-left: $padding;
[dir=rtl] & {
padding: {
left: 0;
right: $padding;
}
}
}
// style.scss
.theme-sample {
@import "theme";
}
Sass 語法
// _theme.sass
ul li
$padding: 16px
padding-left: $padding
[dir=rtl] &
padding:
left: 0
right: $padding
// style.sass
.theme-sample
@import theme
CSS 輸出
.theme-sample ul li {
padding-left: 16px;
}
[dir=rtl] .theme-sample ul li {
padding-left: 0;
padding-right: 16px;
}
導入 CSS導入 CSS 永久連結
- Dart Sass
- 自 1.11.0 版起
- LibSass
- 局部檔案
- Ruby Sass
- ✗
LibSass 支援導入副檔名為 .css
的檔案,但與規範相反,它們被視為 SCSS 檔案,而不是被解析為 CSS。此行為已被棄用,目前正在進行更新以支援以下描述的行為。
除了導入 .sass
和 .scss
檔案之外,Sass 還可以導入普通的 .css
檔案。唯一的規則是導入*不得*明確包含 .css
副檔名,因為該副檔名用於表示 純 CSS @import
。
SCSS 語法
// code.css
code {
padding: .25em;
line-height: 0;
}
// style.scss
@import 'code';
Sass 語法
// code.css
code {
padding: .25em;
line-height: 0;
}
// style.sass
@import code
CSS 輸出
code {
padding: .25em;
line-height: 0;
}
由 Sass 導入的 CSS 檔案不允許任何特殊的 Sass 功能。為了確保作者不會在他們的 CSS 中意外地撰寫 Sass,所有不是有效 CSS 的 Sass 功能都會產生錯誤。否則,CSS 將會按原樣呈現。它甚至可以被 延伸!
純 CSS @import
純 CSS @imports 永久連結
- Dart Sass
- ✓
- LibSass
- 局部檔案
- Ruby Sass
- ✓
LibSass 預設會正確處理一般的 CSS 導入。但是,任何自訂導入器會錯誤地套用至一般 CSS 的 @import
規則,使其有可能載入 Sass 檔案。
由於 @import
也在 CSS 中定義,Sass 需要一種方法在編譯時不嘗試導入檔案的情況下編譯一般的 CSS @import
。為了達成此目的,並確保 SCSS 盡可能成為 CSS 的超集,Sass 會將具有以下特性的任何 @import
編譯成一般的 CSS 導入:
- URL 以
.css
結尾的導入。 - URL 以
http://
或https://
開頭的導入。 - URL 以
url()
形式編寫的導入。 - 具有媒體查詢的導入。
SCSS 語法
@import "theme.css";
@import "http://fonts.googleapis.com/css?family=Droid+Sans";
@import url(theme);
@import "landscape" screen and (orientation: landscape);
Sass 語法
@import "theme.css"
@import "http://fonts.googleapis.com/css?family=Droid+Sans"
@import url(theme)
@import "landscape" screen and (orientation: landscape)
CSS 輸出
@import "theme.css";
@import "http://fonts.googleapis.com/css?family=Droid+Sans";
@import url(theme);
@import "landscape" screen and (orientation: landscape);
插值插值永久連結
雖然 Sass 導入不能使用插值(以確保始終可以判斷Mixin、函式和變數的來源),但一般的 CSS 導入可以使用。這使得可以動態產生導入,例如基於 Mixin 參數。
SCSS 語法
@mixin google-font($family) {
@import url("http://fonts.googleapis.com/css?family=#{$family}");
}
@include google-font("Droid Sans");
Sass 語法
@mixin google-font($family)
@import url("http://fonts.googleapis.com/css?family=#{$family}")
@include google-font("Droid Sans")
CSS 輸出
@import url("http://fonts.googleapis.com/css?family=Droid Sans");
導入與模組導入與模組永久連結
- Dart Sass
- 自 1.23.0 版本起
- LibSass
- ✗
- Ruby Sass
- ✗
目前只有 Dart Sass 支援 @use
。其他實作的使用者必須改用@import
規則。
無論您是導入包含 @use
規則的檔案,還是將包含導入的檔案作為模組載入,Sass 的模組系統都能與 @import
無縫整合。我們希望讓從 @import
到 @use
的過渡盡可能順暢。
導入模組系統檔案導入模組系統檔案永久連結
當您導入包含 @use
規則的檔案時,導入檔案可以存取該檔案中直接定義的所有成員(甚至是私有成員),但*不能*存取該檔案已載入的模組中的任何成員。但是,如果該檔案包含@forward
規則,則導入檔案將可以存取轉發的成員。這表示您可以導入撰寫為與模組系統一起使用的程式庫。
⚠️ 注意!
導入具有 @use
規則的檔案時,這些規則遞迴載入的所有 CSS 都會包含在產生的樣式表中,即使它已被其他導入包含在內。如果您不小心,這可能會導致 CSS 輸出過於龐大!
僅導入檔案僅導入檔案永久連結
適用於 @use
的 API 可能不適用於 @import
。例如,@use
預設會將命名空間新增至所有成員,以便您可以安全地使用簡短名稱,但 @import
不會,因此您可能需要更長的名稱。如果您是程式庫作者,您可能會擔心如果您將程式庫更新為使用新的模組系統,您現有的基於 @import
的使用者會發生錯誤。
為了簡化這個流程,Sass 也支援僅供引入的檔案。如果您將檔案命名為 <name>.import.scss
,它將只會在 @import
時被載入,而不會在 @use
時載入。這樣一來,您就可以維持與使用 @import
的用戶的相容性,同時仍然為使用新模組系統的用戶提供良好的 API。
SCSS 語法
// _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-*;
Sass 語法
// _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-*
透過引入設定模組透過引入設定模組 永久連結
- Dart Sass
- 自 1.24.0 版本起
- LibSass
- ✗
- Ruby Sass
- ✗
您可以透過在第一次載入該模組的 @import
之前定義全域變數來設定透過 @import
載入的模組。
SCSS 語法
// _library.scss
$color: blue !default;
a {
color: $color;
}
// _library.import.scss
@forward 'library' as lib-*;
// style.sass
$lib-color: green;
@import "library";
Sass 語法
$color: blue !default
a
color: $color
// _library.import.sass
@forward 'library' as lib-*
// style.sass
$lib-color: green
@import "library"
CSS 輸出
a {
color: green;
}
⚠️ 注意!
模組只會載入一次,因此如果您在第一次 @import
模組(即使是間接引入)之後更改設定,則再次 @import
該模組時,更改將會被忽略。
載入包含引入的模組載入包含引入的模組 永久連結
當您使用 @use
(或 @forward
)載入使用 @import
的模組時,該模組將包含您載入的樣式表定義的所有公開成員,*以及*該樣式表遞迴引入的所有內容。換句話說,所有引入的內容都會被視為寫在一個大型樣式表中。
即使您依賴的所有函式庫都尚未轉換到新的模組系統,這也讓您可以在樣式表中輕鬆開始使用 @use
。但請注意,如果它們確實轉換了,它們的 API 很可能會改變!