CSS

Parcel 內建支援 CSS。若要加入 CSS 檔案,請在 HTML 檔案中使用 <link> 標籤參照,

<link rel="stylesheet" href="index.css" />

或從 JavaScript 檔案中匯入

import './index.css';

相依性

#

CSS 資產可能包含由 @import 語法參照的相依性,以及透過 url() 函數參照的圖片、字型等。

@import

#

@import at 規則可用於將另一個 CSS 檔案內嵌到與包含檔案相同的 CSS 捆綁中。這表示在執行階段不需要個別的網路要求來載入相依性。

@import 'other.css';

參照的檔案應與包含的 CSS 檔案相對。您也可以使用絕對波浪號指定符。若要從 npm 匯入 CSS 檔案,請使用 npm: 配置

@import 'npm:bootstrap/bootstrap.css';

當啟用 @parcel/resolver-glob 外掛時,您也可以使用 glob 一次匯入多個 CSS 檔案。請參閱Glob 指定符以取得更多詳細資料。

@import "./components/*.css";

url()

#

url() 函數可用於參照檔案,例如背景圖片或字型。參照的檔案將由 Parcel 處理,而 URL 參照將改寫為指向輸出檔名。

body {
background: url(images/background.png);
}

引用的檔案應與包含的 CSS 檔案相對。您也可以使用絕對波浪號指定符號。data-url: 架構也可以用來將檔案內嵌為資料 URL。更多詳細資訊請參閱套件內嵌

.logo {
background: url('data-url:./logo.png');
}

注意:只有絕對路徑可以在 CSS 自訂屬性中使用,不能使用相對路徑。這是因為自訂屬性中的 url() 參考會從使用 var() 的位置解析,而不是自訂屬性定義的位置。這表示自訂屬性可能會解析為不同的 URL,視其在哪些檔案中使用。為了解決這個歧義,請在自訂屬性中參考 URL 時使用絕對路徑。

/src/index.css
body {
/* ❌ relative paths are not allowed in custom properties. */
--logo: url(images/logo.png);
/* ✅ use absolute paths instead. */
--logo: url(/src/images/logo.png);
}
/src/home/header.css
.logo {
background: var(--logo);
}

在上方的範例中,相對路徑 images/logo.png 會解析為 /src/home/images/logo.png,而不是您可能預期的 /src/images/logo.png,因為它在 /src/home/header.css 中被參考。絕對路徑 /src/images/logo.png 會一致解析,不論 var(--logo) 在哪個檔案中使用。

CSS 模組

#

預設情況下,從 JavaScript 匯入的 CSS 是全域的。如果兩個 CSS 檔案定義相同的類別名稱、id、自訂屬性、@keyframes 等,它們可能會衝突並互相覆寫。為了解決這個問題,Parcel 支援CSS 模組

CSS 模組將每個檔案中定義的類別視為獨一無二。每個類別名稱或識別碼都會重新命名,以包含一個唯一的雜湊,並將對應關係匯出至 JavaScript 以供參考。

要使用 CSS 模組,請建立一個副檔名為 .module.css 的檔案,並使用命名空間匯入從 JavaScript 檔案匯入。然後,您可以將 CSS 檔案中定義的每個類別存取為模組的匯出。

import * as classes from './styles.module.css';

document.body.className = classes.body;
.body {
background: skyblue;
}

.body 類別會重新命名為一個獨一無二的名稱,以避免與其他 CSS 檔案的選擇器衝突。

CSS 模組也適用於編譯成 CSS 的其他語言,例如 SASS、Less 或 Stylus。使用對應的檔案副檔名來命名檔案,例如 .module.scss.module.less.module.styl

Tree shaking

#

使用 CSS 模組的另一個好處是,讓程式碼中對特定類別名稱的依賴關係變得明確。這使得未使用的 CSS 類別可以自動移除。

Example of tree shaking CSS modules

如上例所示,只使用了 .button 類別,因此未使用的 .cta 類別會從編譯後的 CSS 檔案中移除。

這也適用於其他未使用的 CSS 規則,例如 @keyframes@counter-style,以及 CSS 自訂屬性(當啟用 dashedIdents 選項時)。

注意:Tree shaking 僅在您使用 命名空間命名 匯入來參照類別時才有效。Tree shaking 不適用於 預設匯入

import styles from './styles.module.css';

應替換為

import * as styles from './styles.module.css';

本機 CSS 變數

#

預設情況下,類別名稱、ID 選擇器以及 @keyframes@counter-style 和 CSS 網格線與區域的名稱會設定範圍,限定在定義這些名稱的模組中。也可以使用專案根目錄 package.json 中的 dashedIdents 設定選項,來啟用 CSS 變數和其他 <dashed-ident> 名稱的範圍設定。

package.json
{
"@parcel/transformer-css": {
"cssModules": {
"dashedIdents": true
}
}
}

啟用後,CSS 變數將會重新命名,以避免與其他檔案中定義的變數名稱衝突。參照變數會使用標準的 var() 語法,Parcel 會更新它以符合局部作用域變數名稱。

您也可以使用 from 關鍵字參照在其他檔案中定義的變數

style.module.css
.button {
background: var(--accent-color from "./vars.module.css");
}
vars.module.css
:root {
--accent-color: hotpink;
}

可以使用 from global 語法參照全域變數,但是,目前必須在非 CSS 模組檔案中定義它們。

style.module.css
@import "vars.css";

.button {
color: var(--color from global);
}
vars.css
:root {
--color: purple;
}

相同的語法也適用於使用 <dashed-ident> 語法的其他 CSS 值。例如,@font-palette-values 規則和 font-palette 屬性使用 <dashed-ident> 語法來定義和參照自訂字型顏色調色盤,並且會以與 CSS 變數相同的方式進行作用域設定和參照。

自訂命名模式

#

預設情況下,Parcel 會在 CSS 檔案中的每個類別名稱和識別碼前面加上檔案名稱的雜湊。您可以使用專案根目錄 package.json 中的 "pattern" 選項來設定此命名模式。這會接受一個包含 Parcel 將填入的佔位符的字串,讓您可以新增自訂前綴或調整作用域類別的命名慣例。

package.json
{
"@parcel/transformer-css": {
"cssModules": {
"pattern": "my-company-[name]-[hash]-[local]"
}
}
}

目前支援下列佔位符

注意:CSS 格線線條名稱可能會因為瀏覽器自動加上字尾而含糊不清,瀏覽器會為每個格線範本區域產生以 -start-end 結尾的線條名稱。在使用 CSS 格線時,您的 "pattern" 設定必須以 [local] 佔位符結尾,才能讓這些參照正確運作。

grid.module.css
.grid {
grid-template-areas: "nav main";
}

.nav {
grid-column-start: nav-start;
}
package.json
{
"@parcel/transformer-css": {
"cssModules": {
// ❌ [local] must be at the end so that
// auto-generated grid line names work
"pattern": "[local]-[hash]"
// ✅ do this instead
"pattern": "[hash]-[local]"
}
}
}

在全域啟用 CSS 模組

#

預設情況下,CSS 模組僅對檔案名稱以 .module.css 結尾的檔案啟用。預設情況下,所有其他 CSS 檔案都視為全域 CSS。不過,這可以透過在專案根目錄的 package.json 中設定 @parcel/transformer-css 來覆寫,以對所有原始檔(即不在 node_modules 中)啟用 CSS 模組。

package.json
{
"@parcel/transformer-css": {
"cssModules": true
}
}

當使用具有其他選項的設定物件時,請改用 "global" 選項。

{
"@parcel/transformer-css": {
"cssModules": {
"global": true,
// ...
}
}
}

注意:在 Parcel 的先前版本中,postcss-modules 用於實作 CSS 模組支援。在專案的 PostCSS 設定檔中啟用全域 CSS 模組。如果你按照上述說明啟用 CSS 模組,現在可以從 PostCSS 設定中移除此外掛程式。

如果這是你使用的唯一 PostCSS 外掛程式,你可以完全移除 PostCSS 設定。這可以大幅改善建置效能。如果你沒有使用任何 postcss-modules 設定選項,你可能會看到這方面的警告。

轉譯

#

Parcel 內建支援將現代 CSS 語法轉譯為支援舊瀏覽器的語法,包括供應商前綴和語法降低。此外,還支援 PostCSS 以啟用自訂 CSS 轉換。

瀏覽器目標

#

預設情況下,Parcel 不會對舊瀏覽器的 CSS 語法執行任何轉譯。這表示如果你使用現代語法或不使用供應商前綴撰寫程式碼,Parcel 會輸出這些內容。你可以使用 package.json 中的 browserslist 欄位宣告應用程式支援的瀏覽器。宣告此欄位後,Parcel 會相應地轉譯你的程式碼,以確保與支援的瀏覽器相容。

package.json
{
"browserslist": "> 0.5%, last 2 versions, not dead"
}

請參閱 目標 文件,以取得如何設定此設定的更多詳細資訊。

供應商前綴

#

根據您設定的瀏覽器目標,Parcel 會自動為許多 CSS 功能新增供應商前綴備用選項。例如,使用 image-set() 函式時,Parcel 也會輸出備用 -webkit-image-set() 值,因為 Chrome 尚未支援未加前綴的值。

.logo {
background: image-set(url(logo.png) 2x, url(logo.png) 1x);
}

編譯為

.logo {
background: -webkit-image-set(url(logo.png) 2x, url(logo.png) 1x);
background: image-set("logo.png" 2x, "logo.png");
}

此外,如果您的 CSS 原始碼(或更可能是函式庫)包含不必要的供應商前綴,Parcel CSS 會自動移除這些前綴以縮小套件大小。例如,在為現代瀏覽器編譯時,將移除 transition 屬性的前綴版本,因為所有瀏覽器都支援未加前綴的版本。

.button {
-webkit-transition: background 200ms;
-moz-transition: background 200ms;
transition: background 200ms;
}

變為

.button {
transition: background .2s;
}

語法降低

#

Parcel 會自動將許多現代 CSS 語法功能編譯為更相容的輸出,您的目標瀏覽器支援這些輸出。

支援下列功能

草案語法

#

Parcel 也可以設定為編譯幾個草案規範,這些規範目前尚未在任何瀏覽器中原生提供。由於這些是草案,語法仍可能變更,因此必須在專案中手動啟用。

巢狀

#

CSS 巢狀 草案規範允許樣式規則巢狀,子規則的選取器以某種方式延伸父選取器。這通常由 SASS 等 CSS 預處理器支援,但有了這個規範,它最終將在瀏覽器中原生支援。Parcel 將此語法編譯為所有瀏覽器目前支援的非巢狀樣式規則。

由於巢狀是草案,因此預設未啟用。若要使用它,請在專案根目錄的 package.json 檔案中設定 @parcel/transformer-css 來啟用它。

package.json
{
"@parcel/transformer-css": {
"drafts": {
"nesting": true
}
}
}

啟用後,專案中的任何 CSS 檔案都可以直接使用巢狀樣式規則或 @nest at 規則。

直接巢狀樣式規則 必須加上 & 巢狀選取器為前綴。這表示父選取器將被替換的地方。例如

.foo {
color: blue;
& > .bar { color: red; }
}

等於

.foo { color: blue; }
.foo > .bar { color: red; }

@nest 規則 允許巢狀,其中父選取器被替換在開頭以外的地方。

.foo {
color: red;
@nest .parent & {
color: blue;
}
}

等於

.foo { color: red; }
.parent .foo { color: blue; }

條件規則,例如 @media,也可以巢狀在樣式規則中,而無需重複選取器。例如

.foo {
display: grid;

@media (orientation: landscape) {
grid-auto-flow: column;
}
}

等於

.foo { display: grid; }

@media (orientation: landscape) {
.foo {
grid-auto-flow: column;
}
}

自訂媒體查詢

#

自訂媒體查詢 的支援包含在 Media Queries Level 5 草案規範中。這允許您定義在 CSS 檔案中多個地方重複使用的媒體查詢。啟用此功能時,Parcel CSS 將提前執行此替換。

例如

@custom-media --modern (color), (hover);

@media (--modern) and (width > 1024px) {
.a { color: green; }
}

等於

@media ((color) or (hover)) and (width > 1024px) {
.a { color: green; }
}

由於自訂媒體查詢為草案,因此預設未啟用。若要使用它們,請在專案根目錄的 package.json 檔案中設定 @parcel/transformer-css 以啟用 customMedia 功能。

package.json
{
"@parcel/transformer-css": {
"drafts": {
"customMedia": true
}
}
}

偽類別替換

#

Parcel 支援將 CSS 偽類別(例如 :focus-visible)替換為可以使用 JavaScript 套用的常規 CSS 類別。這使得為較舊的瀏覽器補充這些偽類別成為可能。

可以在專案根目錄的 package.json 檔案中設定偽類別對應。

package.json
{
"@parcel/transformer-css": {
"pseudoClasses": {
"focusVisible": "focus-visible"
}
}
}

上述設定會將所有選擇器中的 :focus-visible 偽類別替換為 .focus-visible 類別。這讓你可以使用 JavaScript 補充程式,它會適當地套用 .focus-visible 類別。

以下偽類別可以如上所示進行設定

PostCSS

#

PostCSS 是一個使用外掛程式轉換 CSS 的工具。雖然 Parcel 支援與許多常見 PostCSS 外掛程式(例如 autoprefixerpostcss-preset-env)等效的功能,如上所述,但 PostCSS 對於更自訂的 CSS 轉換(例如非標準語法新增)很有用。它也用於流行的 CSS 架構,例如 Tailwind

你可以使用下列其中一個名稱建立設定檔來搭配 Parcel 使用 PostCSS:.postcssrc.postcssrc.json.postcssrc.js.postcssrc.mjs.postcssrc.cjspostcss.config.jspostcss.config.mjspostcss.config.cjs

首先,將你想要使用的 postcss 外掛程式安裝到你的應用程式中

yarn add tailwindcss --dev

然後,建立一個 .postcssrc。外掛程式會在 plugins 物件中指定為金鑰,而選項則使用物件值來定義。如果外掛程式沒有選項,請將其設定為 true

如果你的外掛程式需要額外的組態,也建立那些檔案。例如,使用 Tailwind 時,你需要一個 tailwind.config.js

.postcssrc
{
"plugins": {
"tailwindcss": true
}
}
tailwind.config.js
module.exports = {
content: ["./src/*.{html,js}"],
theme: {
extend: {},
},
variants: {},
plugins: [],
};

預設外掛程式

#

當在 package.json 中指定 browserslist 時,Parcel 會自動包含等同於 autoprefixerpostcss-preset-env 的外掛程式。這些外掛程式會 在 Rust 中實作,而且速度遠比 PostCSS 快。如果這些是你專案中唯一需要的轉換,那麼你可能根本不需要 PostCSS。

如果你有一個現有的專案,其中 PostCSS 組態只包含上述外掛程式,你可能可以完全移除它。如果你正在使用其他外掛程式,你可以移除 autoprefixerpostcss-preset-env,同時只保留自訂外掛程式。這可以大幅改善建置效能,因為 Parcel 的內建轉譯器比 PostCSS 快很多。

請參閱 上方,以取得關於 Parcel 內建轉譯支援的更多詳細資訊。

postcss-import

#

預設情況下,Parcel 會獨立使用 PostCSS 轉換每個 CSS 檔案。然而,有些 PostCSS 外掛程式(例如 postcss-custom-properties)可能需要存取來自其他 @import 的 CSS 資源的宣告。

在這些情況下,你可以使用 postcss-import 來一次在整個套件上執行 PostCSS。也應該使用 postcss-url 來確保當匯入檔案被內嵌時,url() 參照可以正確解析。

.postcssrc
{
"plugins": {
"postcss-import": true,
"postcss-url": true,
"postcss-custom-properties": true
}
}
app.css
@import "./config/index.css";

html {
background-color: var(--varColor);
}

.icon {
width: 50px;
height: 50px;
background-image: var(--varIcon);
}
config/index.css
:root {
--varColor: red;
--varIcon: url("../icon.svg");
}

生產

#

在生產模式中,Parcel 會包含最佳化功能,以減少程式碼檔案大小。請參閱 生產,以取得關於其運作方式的更多詳細資訊。

壓縮

#

在生產模式中,Parcel 會自動壓縮您的程式碼以減少您的套件檔案大小。預設情況下,Parcel 使用 lightningcss 來執行 CSS 壓縮。

注意:在先前版本中,Parcel 使用 cssnano 進行壓縮。如果您的專案包含 cssnano 設定檔,例如 .cssnanorccssnano.config.json,您可能會看到警告,表示在升級 Parcel 後不再套用該設定檔。

在大多數情況下,您只需移除 cssnano 設定檔,並讓 Parcel 處理壓縮即可。但是,如果您確實依賴此設定中的特定設定,並且想要繼續使用 cssnano 而非 lightningcss 進行壓縮,您可以設定 Parcel 改用 @parcel/optimizer-cssnano

.parcelrc
{
"extends": "@parcel/config-default",
"optimizers": {
"*.css": ["@parcel/optimizer-cssnano"]
}
}