執行環境套件管理器打包器測試執行器程式碼檢查格式化指南參考部落格意見回饋

CSS

Bun 的打包工具內建支援帶有現代特性的 CSS

Bun 的打包工具內建支援 CSS,具有以下功能:

  • 將現代/未來特性轉換為可在所有瀏覽器上執行的程式碼(包括新增廠商字首)
  • 壓縮
  • CSS 模組
  • Tailwind(通過原生打包工具外掛)

轉譯

預設啟用轉譯和廠商字首處理,因此你可以使用現代及未來的 CSS 特性,而無需擔心瀏覽器相容性。

Bun 的 CSS 解析器和打包器直接移植自 LightningCSS,其打包方式受 esbuild 啟發。轉譯器會將現代 CSS 語法轉換為向後相容的等效寫法,使其能夠在各種瀏覽器中正常執行。

瀏覽器相容性

預設情況下,Bun 的 CSS 打包目標瀏覽器包括:

  • Edge 80+
  • Firefox 78+
  • Chrome 80+
  • Safari 14+
  • Opera 67+

語法降級

巢狀

藉助 CSS 巢狀,你可以直接在父級程式碼塊中編寫子級樣式,而無需在 CSS 檔案中重複父級選擇器。

styles.css
/* 使用巢狀 */
.card {
  background: white;
  border-radius: 4px;

  .title {
    font-size: 1.2rem;
    font-weight: bold;
  }

  .content {
    padding: 1rem;
  }
}

Bun 的 CSS 打包工具會自動將此巢狀語法轉換成傳統的扁平 CSS,以相容所有瀏覽器:

styles.css
/* 編譯輸出 */
.card {
  background: white;
  border-radius: 4px;
}

.card .title {
  font-size: 1.2rem;
  font-weight: bold;
}

.card .content {
  padding: 1rem;
}

你還可以在選擇器中巢狀媒體查詢和其他 at 規則:

styles.css
.responsive-element {
  display: block;

  @media (min-width: 768px) {
    display: flex;
  }
}

編譯後為:

styles.css
.responsive-element {
  display: block;
}

@media (min-width: 768px) {
  .responsive-element {
    display: flex;
  }
}

顏色混合

color-mix() 函式會在所選色彩空間中按給定比例混合兩種顏色。使用它可以建立顏色變體,而無需自行計算結果值。

styles.css
.button {
  /* 在 RGB 色彩空間中以 30%:70% 混合藍色和紅色 */
  background-color: color-mix(in srgb, blue 30%, red);

  /* 為懸停狀態建立較淺的變體 */
  &:hover {
    background-color: color-mix(in srgb, blue 30%, red, white 20%);
  }
}

Bun 的 CSS 打包工具會在建置時評估這些顏色混合(當所有顏色值已確定,非 CSS 變數),生成適用於所有瀏覽器的靜態顏色值:

styles.css
.button {
  /* 精確計算得到的結果色 */
  background-color: #b31a1a;
}

.button:hover {
  background-color: #c54747;
}

相對顏色

相對顏色語法可以修改現有顏色的單個組成部分。無需重新計算整個顏色,即可調整亮度、飽和度或單獨的顏色通道。

styles.css
.theme-color {
  /* 以基礎色為起點,將亮度增加 15% */
  --accent: lch(from purple calc(l + 15%) c h);

  /* 以我們的品牌藍色為基色,製作一個去飽和版本 */
  --subtle-blue: oklch(from var(--brand-blue) l calc(c * 0.8) h);
}

Bun 的 CSS 打包工具會在建置時計算這些相對顏色修改(不使用 CSS 變數時),生成適用於瀏覽器的靜態顏色值:

styles.css
.theme-color {
  --accent: lch(69.32% 58.34 328.37);
  --subtle-blue: oklch(60.92% 0.112 240.01);
}

可將其用於主題生成、無障礙顏色變體,或根據基礎顏色生成顏色階,而不是為每個值硬編碼。

LAB 顏色

現代 CSS 支援感知均勻的顏色空間 LAB、LCH、OKLAB 和 OKLCH,它們可以表示超出標準 RGB 色域的顏色。

styles.css
.vibrant-element {
  /* 一種超出 sRGB 色域邊界的鮮豔紅色 */
  color: lab(55% 78 35);

  /* 使用感知色彩空間的平滑漸變 */
  background: linear-gradient(to right, oklch(65% 0.25 10deg), oklch(65% 0.25 250deg));
}

Bun 的 CSS 打包器會將這些顏色格式轉換為向後相容的替代方案,以支援不支援這些格式的瀏覽器:

styles.css
.vibrant-element {
  /* 退回到最接近的 RGB 近似 */
  color: #ff0f52;
  /* 支援更寬色域的瀏覽器使用 P3 備選 */
  color: color(display-p3 1 0.12 0.37);
  /* 支援該格式的瀏覽器保持原值 */
  color: lab(55% 78 35);

  background: linear-gradient(to right, #cd4e15, #3887ab);
  background: linear-gradient(to right, oklch(65% 0.25 10deg), oklch(65% 0.25 250deg));
}

顏色函式

color() 函式可以在傳統 RGB 之外的預定義色彩空間中指定顏色,讓你能夠使用更寬的色域。

styles.css
.vivid-element {
  /* 使用 Display P3 色彩空間實現更寬色域 */
  color: color(display-p3 1 0.1 0.3);

  /* 使用 A98 RGB 色彩空間 */
  background-color: color(a98-rgb 0.44 0.5 0.37);
}

對於不支援這些色彩空間的瀏覽器,Bun 的 CSS 打包器會新增 RGB 備選值:

styles.css
.vivid-element {
  /* 優先使用 RGB 備選以獲得最大相容 */
  color: #fa1a4c;
  /* 保留原色以支援相容瀏覽器 */
  color: color(display-p3 1 0.1 0.3);

  background-color: #6a805d;
  background-color: color(a98-rgb 0.44 0.5 0.37);
}

HWB 顏色

HWB(色相、白度、黑度)顏色模型基於純色相中混合了多少白色或黑色來表示顏色。與 RGB 或 HSL 值相比,使用這種方式可以更直接地建立淺色和深色變體。

styles.css
.easy-theming {
  /* 純青色,無白無黑 */
  --primary: hwb(180 0% 0%);

  /* 同色相,加入 20% 白色(色調) */
  --primary-light: hwb(180 20% 0%);

  /* 同色相,加入 30% 黑色(陰影) */
  --primary-dark: hwb(180 0% 30%);

  /* 新增白色和黑色的柔和版本 */
  --primary-muted: hwb(180 30% 20%);
}

Bun 的 CSS 打包器會將 HWB 顏色轉換為 RGB,以相容所有瀏覽器:

styles.css
.easy-theming {
  --primary: #00ffff;
  --primary-light: #33ffff;
  --primary-dark: #00b3b3;
  --primary-muted: #339999;
}

顏色表示法

現代 CSS 支援使用空格分隔的 RGB 和 HSL 值(不帶逗號),以及帶 alpha 通道的十六進位制顏色。

styles.css
.modern-styling {
  /* 空格分隔的 RGB 表示法(無逗號) */
  color: rgb(50 100 200);

  /* 空格分隔帶 alpha 的 RGB */
  border-color: rgba(100 50 200 / 75%);

  /* 帶 alpha 通道的 8 位十六進位制 */
  background-color: #00aaff80;

  /* 簡化的 HSL 表示 */
  box-shadow: 0 5px 10px hsl(200 50% 30% / 40%);
}

Bun 的 CSS 打包器會將這些格式轉換為舊版瀏覽器支援的格式:

styles.css
.modern-styling {
  /* 轉為舊版需要的逗號格式 */
  color: rgb(50, 100, 200);

  /* 透明度通道妥善處理 */
  border-color: rgba(100, 50, 200, 0.75);

  /* 十六進位制帶 alpha 轉為 rgba */
  background-color: rgba(0, 170, 255, 0.5);

  box-shadow: 0 5px 10px rgba(38, 115, 153, 0.4);
}

light-dark() 顏色函式

light-dark() 函式接受兩種顏色,並根據當前顏色方案應用其中一種,使樣式無需使用媒體查詢即可遵循使用者的系統偏好。

styles.css
:root {
  /* 定義支援的顏色方案 */
  color-scheme: light dark;
}

.themed-component {
  /* 根據系統偏好自動選擇顏色 */
  background-color: light-dark(#ffffff, #121212);
  color: light-dark(#333333, #eeeeee);
  border-color: light-dark(#dddddd, #555555);
}

/* 需要時覆蓋系統偏好 */
.light-theme {
  color-scheme: light;
}

.dark-theme {
  color-scheme: dark;
}

對於不支援 light-dark() 的瀏覽器,Bun 的 CSS 打包器會將其轉換為帶有回退值的 CSS 變數:

styles.css
:root {
  --buncss-light: initial;
  --buncss-dark: ;
  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root {
    --buncss-light: ;
    --buncss-dark: initial;
  }
}

.light-theme {
  --buncss-light: initial;
  --buncss-dark: ;
  color-scheme: light;
}

.dark-theme {
  --buncss-light: ;
  --buncss-dark: initial;
  color-scheme: dark;
}

.themed-component {
  background-color: var(--buncss-light, #ffffff) var(--buncss-dark, #121212);
  color: var(--buncss-light, #333333) var(--buncss-dark, #eeeeee);
  border-color: var(--buncss-light, #dddddd) var(--buncss-dark, #555555);
}

邏輯屬性

CSS 邏輯屬性根據文件的書寫模式和文本方向,而不是螢幕的物理方向來定義佈局、間距和尺寸,因此佈局可以適應不同的書寫系統。

styles.css
.multilingual-component {
  /* 適應書寫方向的外邊距 */
  margin-inline-start: 1rem;

  /* 無論文本方向,都合理的內邊距 */
  padding-block: 1rem 2rem;

  /* 頂部起始角的邊框半徑 */
  border-start-start-radius: 4px;

  /* 尊重書寫模式的尺寸 */
  inline-size: 80%;
  block-size: auto;
}

對於不完全支援邏輯屬性的瀏覽器,Bun 的 CSS 打包器會針對每種文本方向將其編譯為物理屬性:

styles.css
/* 左到右語言 */
.multilingual-component:dir(ltr) {
  margin-left: 1rem;
  padding-top: 1rem;
  padding-bottom: 2rem;
  border-top-left-radius: 4px;
  width: 80%;
  height: auto;
}

/* 右到左語言 */
.multilingual-component:dir(rtl) {
  margin-right: 1rem;
  padding-top: 1rem;
  padding-bottom: 2rem;
  border-top-right-radius: 4px;
  width: 80%;
  height: auto;
}

如果不支援 :dir() 選擇器,Bun 會生成額外的回退方案。

:dir() 選擇器

:dir() 偽類根據元素的文本方向(RTL 或 LTR)設定樣式,該方向由文件或顯式的 direction 屬性決定。使用它可以編寫無需 JavaScript 的方向感知樣式。

styles.css
/* 根據文本方向應用不同樣式 */
.nav-arrow:dir(ltr) {
  transform: rotate(0deg);
}

.nav-arrow:dir(rtl) {
  transform: rotate(180deg);
}

/* 基於文本流的位置定位元素 */
.sidebar:dir(ltr) {
  border-right: 1px solid #ddd;
}

.sidebar:dir(rtl) {
  border-left: 1px solid #ddd;
}

對於不支援 :dir() 選擇器的瀏覽器,Bun 的 CSS 打包器會將其轉換為相容性更廣的 :lang() 選擇器,並使用適當的語言對映:

styles.css
/* 作為回退轉換為基於語言的選擇器 */
.nav-arrow:lang(en, fr, de, es, it, pt, nl) {
  transform: rotate(0deg);
}

.nav-arrow:lang(ar, he, fa, ur) {
  transform: rotate(180deg);
}

.sidebar:lang(en, fr, de, es, it, pt, nl) {
  border-right: 1px solid #ddd;
}

.sidebar:lang(ar, he, fa, ur) {
  border-left: 1px solid #ddd;
}

如果不支援向 :lang() 傳入多個引數,Bun 會生成進一步的回退方案。

:lang() 選擇器

:lang() 偽類根據元素的語言定位元素。要為相關語言組合規則,可以向單個 :lang() 傳入多個語言程式碼。

styles.css
/* 針對中日韓語言的排版調整 */
:lang(zh, ja, ko) {
  line-height: 1.8;
  font-size: 1.05em;
}

/* 不同語言組的引號樣式 */
blockquote:lang(fr, it, es, pt) {
  font-style: italic;
}

blockquote:lang(de, nl, da, sv) {
  font-weight: 500;
}

對於不支援在 :lang() 選擇器中使用多個引數的瀏覽器,Bun 的 CSS 打包器會將此語法轉換為行為相同的 :is() 選擇器:

styles.css
/* 使用 :is() 組合多個語言以提高相容 */
:is(:lang(zh), :lang(ja), :lang(ko)) {
  line-height: 1.8;
  font-size: 1.05em;
}

blockquote:is(:lang(fr), :lang(it), :lang(es), :lang(pt)) {
  font-style: italic;
}

blockquote:is(:lang(de), :lang(nl), :lang(da), :lang(sv)) {
  font-weight: 500;
}

如果需要,Bun 還可以為 :is() 生成額外的回退方案。

:is() 選擇器

:is() 偽類函式(之前稱為 :matches())接收一個選擇器列表,如果列表中的任意選擇器匹配,則匹配成功。

styles.css
/* 不用分別寫這些 */
/* 
.article h1,
.article h2,
.article h3 {
  margin-top: 1.5em;
}
*/

/* 可以寫成 */
.article :is(h1, h2, h3) {
  margin-top: 1.5em;
}

/* 複雜範例,多個組合 */
:is(header, main, footer) :is(h1, h2, .title) {
  font-family: "Heading Font", sans-serif;
}

對於不支援 :is() 的瀏覽器,Bun 的 CSS 打包工具提供使用廠商字首的替代寫法:

CSS
/* 使用 -webkit-any 回退 */
.article :-webkit-any(h1, h2, h3) {
  margin-top: 1.5em;
}

/* 使用 -moz-any 回退 */
.article :-moz-any(h1, h2, h3) {
  margin-top: 1.5em;
}

/* 現代瀏覽器保留原寫法 */
.article :is(h1, h2, h3) {
  margin-top: 1.5em;
}

/* 複雜範例的回退 */
:-webkit-any(header, main, footer) :-webkit-any(h1, h2, .title) {
  font-family: "Heading Font", sans-serif;
}

:-moz-any(header, main, footer) :-moz-any(h1, h2, .title) {
  font-family: "Heading Font", sans-serif;
}

:is(header, main, footer) :is(h1, h2, .title) {
  font-family: "Heading Font", sans-serif;
}

:not() 選擇器

:not() 偽類會排除匹配某個選擇器的元素。現代版本支援多個引數,可以通過一個 :not() 排除多種模式。

styles.css
/* 選擇所有按鈕,排除主按鈕和次按鈕 */
button:not(.primary, .secondary) {
  background-color: #f5f5f5;
  border: 1px solid #ddd;
}

/* 應用樣式於所有標題,排除側邊欄或頁尾內的 */
h2:not(.sidebar *, footer *) {
  margin-top: 2em;
}

對於不支援 :not() 中多個引數的瀏覽器,Bun 的 CSS 打包器會將此語法轉換為行為相同且相容性更好的形式:

styles.css
/* 轉換為使用帶 :is() 的 :not() */
button:not(:is(.primary, .secondary)) {
  background-color: #f5f5f5;
  border: 1px solid #ddd;
}

h2:not(:is(.sidebar *, footer *)) {
  margin-top: 2em;
}

如果不支援 :is(),Bun 會生成進一步的回退:

styles.css
/* 額外回退以確保最大相容 */
button:not(:-webkit-any(.primary, .secondary)) {
  background-color: #f5f5f5;
  border: 1px solid #ddd;
}

button:not(:-moz-any(.primary, .secondary)) {
  background-color: #f5f5f5;
  border: 1px solid #ddd;
}

button:not(:is(.primary, .secondary)) {
  background-color: #f5f5f5;
  border: 1px solid #ddd;
}

轉換後的選擇器保留了原始選擇器的優先順序和行為。

數學函式

CSS 包含以下數學函式:

  • 標準數學函式:round()、mod()、rem()、abs()、sign()
  • 三角函式:sin()、cos()、tan()、asin()、acos()、atan()、atan2()
  • 指數函式:pow()、sqrt()、exp()、log()、hypot()
styles.css
.dynamic-sizing {
  /* 限定值在最小和最大之間 */
  width: clamp(200px, 50%, 800px);

  /* 四捨五入到最接近的倍數 */
  padding: round(14.8px, 5px);

  /* 動畫或佈局的三角函式 */
  transform: rotate(calc(sin(45deg) * 50deg));

  /* 組合多個函式的複雜數學 */
  --scale-factor: pow(1.25, 3);
  font-size: calc(16px * var(--scale-factor));
}

當所有值都是已知常量(而非變數)時,Bun 的 CSS 打包器會在建置時計算這些表示式:

styles.css
.dynamic-sizing {
  width: clamp(200px, 50%, 800px);
  padding: 15px;
  transform: rotate(35.36deg);
  --scale-factor: 1.953125;
  font-size: calc(16px * var(--scale-factor));
}

媒體查詢範圍

媒體查詢範圍語法使用比較運算子(<、>、<=、>=)表示斷點,而不是使用更冗長的 min- 和 max- 字首。

styles.css
/* 比較運算子的現代寫法 */
@media (width >= 768px) {
  .container {
    max-width: 720px;
  }
}

/* 使用 <= 和 >= 的包含範圍 */
@media (768px <= width <= 1199px) {
  .sidebar {
    display: flex;
  }
}

/* 使用 < 和 > 的排他範圍 */
@media (width > 320px) and (width < 768px) {
  .mobile-only {
    display: block;
  }
}

Bun 的 CSS 打包器會將範圍查詢轉換為傳統的媒體查詢語法,以相容所有瀏覽器:

styles.css
/* 轉換為傳統 min/max 語法 */
@media (min-width: 768px) {
  .container {
    max-width: 720px;
  }
}

@media (min-width: 768px) and (max-width: 1199px) {
  .sidebar {
    display: flex;
  }
}

@media (min-width: 321px) and (max-width: 767px) {
  .mobile-only {
    display: block;
  }
}

簡寫屬性

CSS 引入了幾種將多個長屬性組合在一起的簡寫屬性。

styles.css
/* 對齊簡寫 */
.flex-container {
  /* align-items 和 justify-items 的簡寫 */
  place-items: center start;

  /* align-content 和 justify-content 的簡寫 */
  place-content: space-between center;
}

.grid-item {
  /* align-self 和 justify-self 的簡寫 */
  place-self: end center;
}

/* 雙值溢位屬性 */
.content-box {
  /* 第一個值對應水平,第二個垂直 */
  overflow: hidden auto;
}

/* 增強的文本裝飾 */
.fancy-link {
  /* 結合多條文本裝飾屬性 */
  text-decoration: underline dotted blue 2px;
}

/* 雙值 display 語法 */
.component {
  /* 外層和內層顯示型別 */
  display: inline flex;
}

對於不支援這些簡寫屬性的瀏覽器,Bun 會將它們轉換為對應的元件長屬性:

styles.css
.flex-container {
  /* 展開對齊屬性 */
  align-items: center;
  justify-items: start;

  align-content: space-between;
  justify-content: center;
}

.grid-item {
  align-self: end;
  justify-self: center;
}

.content-box {
  /* 分別控制溢位方向 */
  overflow-x: hidden;
  overflow-y: auto;
}

.fancy-link {
  /* 單獨文本裝飾屬性 */
  text-decoration-line: underline;
  text-decoration-style: dotted;
  text-decoration-color: blue;
  text-decoration-thickness: 2px;
}

.component {
  /* 單值 display */
  display: inline-flex;
}

雙位置漸變

雙位置漸變語法會在兩個相鄰位置指定相同的顏色,從而建立硬色標:產生銳利的過渡,而不是平滑的漸變。它適用於條紋、色帶以及其他多色設計。

styles.css
.striped-background {
  /* 在 30%-40% 製造綠色到紅色的硬切換 */
  background: linear-gradient(
    to right,
    yellow 0%,
    green 20%,
    green 30%,
    red 30%,
    /* 雙點位置製造硬邊界 */ red 70%,
    blue 70%,
    blue 100%
  );
}

.progress-bar {
  /* 製造明顯色塊 */
  background: linear-gradient(
    to right,
    #4caf50 0% 25%,
    /* 綠色從 0% 到 25% */ #ffc107 25% 50%,
    /* 黃色從 25% 到 50% */ #2196f3 50% 75%,
    /* 藍色從 50% 到 75% */ #9c27b0 75% 100% /* 紫色從 75% 到 100% */
  );
}

對於不支援此語法的瀏覽器,Bun 的 CSS 打包器會通過複製顏色標記,將其轉換為傳統格式:

styles.css
.striped-background {
  background: linear-gradient(
    to right,
    yellow 0%,
    green 20%,
    green 30%,
    red 30%,
    /* 分成兩段色點 */ red 70%,
    blue 70%,
    blue 100%
  );
}

.progress-bar {
  background: linear-gradient(
    to right,
    #4caf50 0%,
    #4caf50 25%,
    /* 兩段色點綠段 */ #ffc107 25%,
    #ffc107 50%,
    /* 兩段色點黃段 */ #2196f3 50%,
    #2196f3 75%,
    /* 兩段色點藍段 */ #9c27b0 75%,
    #9c27b0 100% /* 兩段色點紫段 */
  );
}

system-ui 字型

system-ui 通用字體系列使用裝置的原生 UI 字型。

styles.css
.native-interface {
  /* 使用系統預設 UI 字型 */
  font-family: system-ui;
}

.fallback-aware {
  /* 帶顯式回退的系統 UI 字型 */
  font-family: system-ui, sans-serif;
}

對於不支援 system-ui 的瀏覽器,Bun 的 CSS 打包器會將其擴充套件為跨平臺字型堆疊:

styles.css
.native-interface {
  /* 為所有主流平臺擴充套件 */
  font-family:
    system-ui,
    -apple-system,
    BlinkMacSystemFont,
    "Segoe UI",
    Roboto,
    "Noto Sans",
    Ubuntu,
    Cantarell,
    "Helvetica Neue";
}

.fallback-aware {
  /* 擴充套件字型堆疊後保留原輪廓回退 */
  font-family:
    system-ui,
    -apple-system,
    BlinkMacSystemFont,
    "Segoe UI",
    Roboto,
    "Noto Sans",
    Ubuntu,
    Cantarell,
    "Helvetica Neue",
    sans-serif;
}

擴充套件後的字型堆疊包含適用於 macOS/iOS、Windows、Android 和 Linux 的系統字型,以及針對舊版瀏覽器的回退字型。

CSS 模組

Bun 的打包器還支援 CSS 模組,具有以下功能:

  • 無需設定即可檢測 CSS 模組檔案(.module.css)
  • 組合(composes 屬性)
  • 將 CSS 模組匯入 JSX/TSX
  • 針對 CSS 模組無效用法的警告/錯誤

CSS 模組是一種 CSS 檔案(副檔名為 .module.css),其中所有類名和動畫都限定在該檔案的作用域內。這有助於避免類名衝突,因為 CSS 宣告預設是全域性作用域的。

Bun 的打包器會將區域性作用域的類名轉換為唯一識別符號。

快速入門

建立一個以 .module.css 結尾的 CSS 檔案:

styles.module.css
.button {
  color: red;
}
other-styles.module.css
.button {
  color: blue;
}

然後你可以匯入此檔案,比如在 TSX 檔案中:

app.tsx
import styles from "./styles.module.css";
import otherStyles from "./other-styles.module.css";

export default function App() {
  return (
    <>
      <button className={styles.button}>紅色按鈕!</button>
      <button className={otherStyles.button}>藍色按鈕!</button>
    </>
  );
}

匯入 CSS 模組會得到一個物件,該物件將每個類名對映到其唯一識別符號:

app.tsx
import styles from "./styles.module.css";
import otherStyles from "./other-styles.module.css";

console.log(styles);
console.log(otherStyles);

輸出結果如下:

app.tsx
{
  button: "button_123";
}

{
  button: "button_456";
}

每個檔案中的類名都是唯一的,因此不會發生衝突。

組合

CSS 模組可以將類選擇器組合在一起,以便在多個類之間複用樣式規則。

例如:

styles.module.css
.button {
  composes: background;
  color: red;
}

.background {
  background-color: blue;
}

這與以下寫法相同:

styles.module.css
.button {
  background-color: blue;
  color: red;
}

.background {
  background-color: blue;
}

使用 composes 時需要遵循以下兩條規則:

styles.module.css
#button {
  /* 無效!`#button` 不是類選擇器 */
  composes: background;
}

.button,
.button-secondary {
  /* 無效!`.button, .button-secondary` 不是簡單選擇器 */
  composes: background;
}

從獨立 CSS 模組檔案組合

你也可以從其他 CSS 模組檔案中組合類:

background.module.css
.background {
  background-color: blue;
}
styles.module.css
.button {
  composes: background from "./background.module.css";
  color: red;
}