CSS 巢狀

我們最喜愛的其中一項 CSS 預先處理工具功能現已內建在程式語言中:巢狀樣式規則。

亞當阿爾蓋爾
Adam Argyle

在建立巢狀結構之前,您必須明確宣告每個選取器,與其他選取條件分開。這會導致重複、樣式表大量和撰寫不整的內容。

完成前
.nesting {
  color: hotpink;
}

.nesting > .is {
  color: rebeccapurple;
}

.nesting > .is > .awesome {
  color: deeppink;
}

巢狀結構之後,即可繼續選取器,相關樣式規則可以分組。

完成後
.nesting {
  color: hotpink;

  > .is {
    color: rebeccapurple;

    > .awesome {
      color: deeppink;
    }
  }
}

在瀏覽器中試用

巢狀結構可減少開發人員的需求重複選取條件,同時為相關元素定位樣式規則。也可以協助樣式符合指定的 HTML。如果上一個範例中的 .nesting 元件已從專案中移除,您可以刪除整個群組,而不必搜尋相關選取器執行個體的檔案。

巢狀結構的用途如下: - 機構 - 縮減檔案大小 - 重構

Nesting 適用於 Chrome 112,也可以在 Safari 技術預覽版 162 中試用

開始使用 CSS 巢狀結構

在本文其餘部分,下列示範沙箱將協助您以視覺化方式呈現選項。在此預設狀態下,系統不會選取任何項目,所有內容都會顯示。選擇各種形狀和大小後,您就能練習語法並看看實際運作情形。

色彩繽紛的格線,內含大小圓圈、三角形和正方形。

沙箱中則有圓形、三角形和正方形。分別有小型、中或大其他則為藍色、粉紅色或紫色。這些這些項目全都位於包含元素的 .demo 內。以下為將指定的 HTML 元素預覽。

<div class="demo">
  <div class="sm triangle pink"></div>
  <div class="sm triangle blue"></div>
  <div class="square blue"></div>
  <div class="sm square pink"></div>
  <div class="sm square blue"></div>
  <div class="circle pink"></div>
  …
</div>

巢狀結構範例

CSS 巢狀結構可讓您在另一個選取器的內容中定義元素的樣式。

.parent {
  color: blue;

  .child {
    color: red;
  }
}

在這個範例中,.child 類別選取器是在 .parent 類別選取器內以巢狀結構建立。這表示巢狀 .child 選取器僅適用於具有 .parent 類別的元素子項元素。

或者,您也可以使用 & 符號編寫此範例,明確指出父項類別應放置在何處。

.parent {
  color: blue;

  & .child {
    color: red;
  }
}

這兩個範例具有作用,且隨著本文的深入探討範例,您會有選擇的原因更加清楚。

選取社交圈

在這個第一個範例中,工作是新增樣式來淡出,並只模糊處理示範內的圓形。

如果沒有巢狀結構,CSS 目前會發生以下情況:

.demo .circle {
  opacity: .25;
  filter: blur(25px);
}

使用巢狀結構時,有效做法有以下兩種:

/* & is explicitly placed in front of .circle */
.demo {
  & .circle {
    opacity: .25;
    filter: blur(25px);
  }
}

/* & + " " space is added for you */
.demo {
  .circle {
    opacity: .25;
    filter: blur(25px);
  }
}

結果,在 .demo 中使用 .circle 類別的所有元素均會模糊處理,且幾乎不可見:

彩色的形狀格線不再有圓形,背景是很模糊的。
立即試用

選取任一三角形和正方形

這項工作需要選取多個巢狀元素,也就是所謂的群組選取器

如未建立巢狀結構,CSS 供應商有兩種做法:

.demo .triangle,
.demo .square {
  opacity: .25;
  filter: blur(25px);
}

或使用 :is()

/* grouped with :is() */
.demo :is(.triangle, .square) {
  opacity: .25;
  filter: blur(25px);
}

使用巢狀結構時,可採用以下兩種方式:

.demo {
  & .triangle,
  & .square {
    opacity: .25;
    filter: blur(25px);
  }
}

.demo {
  .triangle, .square {
    opacity: .25;
    filter: blur(25px);
  }
}

結果,只有 .circle 元素會保留在 .demo 中:

彩色的形狀網格中只有圓形,所有其他形狀都幾乎看不見。
立即試用

選取大三角形和圓形

這項工作需要「複合選取器」,其中元素必須同時具有兩個類別,才能進行選取。

如果沒有巢狀結構,CSS 目前會發生以下情況:

.demo .lg.triangle,
.demo .lg.square {
  opacity: .25;
  filter: blur(25px);
}

.demo .lg:is(.triangle, .circle) {
  opacity: .25;
  filter: blur(25px);
}

使用巢狀結構時,可採用以下兩種方式:

.demo {
  .lg.triangle,
  .lg.circle {
    opacity: .25;
    filter: blur(25px);
  }
}

.demo {
  .lg {
    &.triangle,
    &.circle {
      opacity: .25;
      filter: blur(25px);
    }
  }
}

結果,所有大型三角形和圓形都會隱藏在 .demo 中:

彩色的格狀空間只會顯示中小型的圖形。
立即試用
提供複合選取器和巢狀結構的專家級提示

& 符號是您的好友,因為該符號會明確展示如何加入巢狀選取器。請參考以下範例:

.demo {
  .lg {
    .triangle,
    .circle {
      opacity: .25;
      filter: blur(25px);
    }
  }
}

雖然建立巢狀結構的有效方式,但結果不會與您可能會預期的元素相符。這是因為如果沒有 & 指定將 .lg.triangle, .lg.circle 合併的所需結果,實際結果會是 .lg .triangle, .lg .circle子選取器

選取所有粉紅色形狀以外的所有形狀

這項工作需要「否定函式虛擬類別」,其中元素不得具有指定的選取器。

如果沒有巢狀結構,CSS 目前會發生以下情況:

.demo :not(.pink) {
  opacity: .25;
  filter: blur(25px);
}

使用巢狀結構時,可採用以下兩種方式:

.demo {
  :not(.pink) {
    opacity: .25;
    filter: blur(25px);
  }
}

.demo {
  & :not(.pink) {
    opacity: .25;
    filter: blur(25px);
  }
}

結果,所有非粉紅色的形狀都會隱藏在 .demo 中:

彩色格線現在是單色,只會顯示粉紅色圖形。
立即試用
運用 & 提高精確度與彈性

假設您想要使用 :not() 選取器指定「.demo」。為此,「必要」&

.demo {
  &:not() {
    ...
  }
}

這會將 .demo:not() 合併為 .demo:not(),而非上一個需要 .demo :not() 的範例。如果要以巢狀方式建立 :hover 互動,這個提醒非常重要。

.demo {
  &:hover {
    /* .demo:hover */
  }

  :hover {
    /* .demo :hover */
  }
}

更多巢狀結構範例

適用於巢狀結構的 CSS 規格提供更多範例。若想透過範例進一步瞭解語法,也會提供許多有效和無效範例。

接下來的幾個範例將簡單介紹 CSS 巢狀功能,協助您瞭解它所介紹的功能。

建立 @media 巢狀結構

移動至樣式表的不同區域,找出修改選取器及其樣式的媒體查詢條件,可能會非常分散。能夠直接在語境內建立巢狀結構條件,而會造成乾擾。

為方便語法,如果巢狀媒體查詢只是修改目前選取器內容的樣式,系統會使用基本語法。

.card {
  font-size: 1rem;

  @media (width >= 1024px) {
    font-size: 1.25rem;
  }
}

明確使用 & 也可以:

.card {
  font-size: 1rem;

  @media (width >= 1024px) {
    &.large {
      font-size: 1.25rem;
    }
  }
}

這個範例顯示使用 & 的擴充語法,同時指定 .large 資訊卡來示範其他巢狀結構功能仍可正常運作。

進一步瞭解如何建立巢狀 @rules

在任何位置建立巢狀結構

到目前為止,所有範例均已繼續,或附加至先前的背景資訊。 您可以視需要完全變更或重新排列背景資訊。

.card {
  .featured & {
    /* .featured .card */
  }
}

& 符號代表選取器物件 (非字串) 的參照,可以放在巢狀選取器中的任何位置。甚至可以多次放置:

.card {
  .featured & & & {
    /* .featured .card .card .card */
  }
}

雖然本範例有點不需使用,但在某些情況下,重複選取選取器結構定義時就可派上用場。

無效的巢狀結構範例

有幾種巢狀語法情境無效,如果您原本使用巢狀處理工具,可能會感到意外。

巢狀與串連

許多 CSS 類別命名慣例都仰賴巢狀結構,以便將選取器當成字串串連或附加。這不適用於 CSS 巢狀結構,因為選取器不是字串,而是物件參照。

.card {
  &--header {
    /* is not equal to ".card--header" */
  }
}

如需更詳盡的說明,請參閱規格

虛構的巢狀結構範例

選取器清單和 :is() 中的巢狀結構

請考慮使用以下巢狀 CSS 區塊:

.one, #two {
  .three {
    /* some styles */
  }
}

這是第一個範例,開頭為選取器清單,然後繼續建立巢狀結構。先前的範例只結束了選取器清單。在這個巢狀結構範例中,沒有無效之處,但是在選擇器清單中加入巢狀結構時,可能有些棘手的導入詳細資訊,尤其是包含 ID 選取器的實作方式。

為了讓巢狀結構正常運作,瀏覽器會將所有非最內層的選取器清單包裝在 :is() 中。這麼做能保留選取器清單在任何已編寫內容的分組方式。這個群組 :is(.one, #two) 的副作用是採用括號內最高分數的明確性。這也是 :is() 一律的運作方式,不過使用巢狀語法時可能會讓您感到驚訝,因為與其編寫的內容並非完全相同。重點摘要;如果將 ID 和選取器清單加入巢狀結構,就能產生非常明確的選取器。

為清楚說明這個棘手的範例,系統會將先前的巢狀區塊套用至文件,如下所示:

:is(.one, #two) .three {
  /* some styles */
}

在使用 ID 選取器的選取工具清單中建立巢狀結構時,請特別留意或教導 Linter 警告,該選取器清單中所有巢狀結構的明確程度將會高。

混合巢狀和宣告

請考慮使用以下巢狀 CSS 區塊:

.card {
  color: green;
  & { color: blue; }
  color: red;
}

.card 元素的顏色將為 blue

所有混用的樣式宣告都會提升至頂端,如同在任何巢狀結構發生前編寫一樣。詳情請參閱規格

但你可以這麼做,以下程式碼會納入 & 中的三個顏色樣式,這些樣式會依照作者的預期方式維持排列順序。.card 元素的顏色將是紅色。

.card {
  color: green;
  & { color: blue; }
  & { color: red; }
}

事實上,建議您利用 & 納入後續建立巢狀結構的任何樣式。

.card {
  color: green;

  @media (prefers-color-scheme: dark) {
    color: lightgreen;
  }

  & {
    aspect-ratio: 4/3;
  }
}

特徵偵測

你可以透過兩種方式偵測 CSS 巢狀結構:使用巢狀結構或使用 @supports 檢查巢狀選取器剖析功能。

Bramus 的 Codepen 示範螢幕截圖,詢問瀏覽器是否支援 CSS 巢狀結構。該問題下方會顯示一個綠色方塊,表示支援。

使用巢狀結構:

html {
  .has-nesting {
    display: block;
  }

  .no-nesting {
    display: none;
  }
}

使用 @supports

@supports (selector(&)) {
  /* nesting parsing available */
}

我的同事 Bramus超棒的 Codepen 介紹這項策略。

使用 Chrome 開發人員工具偵錯

目前的開發人員工具對巢狀結構的支援最少。目前,您會發現「Styles」窗格中會如預期呈現樣式,但還不支援追蹤巢狀結構及其完整的選取器內容。因此我們在設計和計畫 開誠佈公

Chrome 開發人員工具巢狀語法的螢幕截圖。

Chrome 113 計劃進一步支援 CSS 巢狀結構。我們日後會再發佈相關消息,敬請密切注意。

日後規劃

CSS Nesting 目前為第 1 版。 第 2 版將推出更多語法糖,而且可能較少用於記憶的規則。巢狀結構的剖析要求數量很多,因此是不受限製或難以處理的棘手時刻。

巢狀結構是 CSS 語言的一大強化項目。它也對 CSS 架構方面的所有層面造成影響如果要有效指定版本 2,您必須先深入瞭解並理解這種巨大的影響。

最後的一項概念是此示範同時使用 @scope、巢狀結構和 @layer。真是令人興奮!

灰色背景上有淺色資訊卡。這張資訊卡包含標題、文字、幾個動作按鈕,以及網路龐克風格圖片。