我們最喜愛的 CSS 前置處理器功能之一現在已內建於語言中:巢狀樣式規則。
在建立巢狀結構之前,需要明確宣告每個選取器,彼此之間都必須分開宣告。這會導致重複、大量的樣式表單和零散的撰寫體驗。
.nesting { color: hotpink; } .nesting > .is { color: rebeccapurple; } .nesting > .is > .awesome { color: deeppink; }
巢狀後,您可以繼續使用選取器,並將相關樣式規則分組。
.nesting { color: hotpink; > .is { color: rebeccapurple; > .awesome { color: deeppink; } } }
巢狀結構可協助開發人員減少需要重複的選取器,同時將相關元素的樣式規則設為共置。此外,樣式也有助於
與指定的 HTML 相符如果先前範例中的 .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);
}
}
結果:.demo
中只剩下 .circle
元素:
選取大型三角形和圓形
這項任務需要複合選取器,元素必須同時具備兩個類別,才能選取。
不使用巢狀結構的 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
來檢查巢狀選取器剖析功能。
使用巢狀結構:
html {
.has-nesting {
display: block;
}
.no-nesting {
display: none;
}
}
使用 @supports
:
@supports (selector(&)) {
/* nesting parsing available */
}
我的同事 Bramus 有一個很棒的 Codepen,說明這項策略。
使用 Chrome 開發人員工具進行偵錯
開發人員工具目前的巢狀結構支援最少。目前您會發現樣式會如預期顯示在「樣式」窗格中,但系統尚不支援追蹤巢狀結構和完整的選取器內容。我們有相關設計和計畫,以便讓這項功能更公開透明。
Chrome 113 預計將額外支援 CSS 巢狀結構。敬請期待!
未來
CSS Nesting 目前僅支援第 1 版。第 2 版將推出更多語法糖,並可能減少需要記憶的規則。許多人希望巢狀解析作業不會受到限制,或不會出現棘手的情況。
巢狀結構是 CSS 語言的重大強化功能。這項技術對 CSS 幾乎所有架構層面都有影響。在有效指定第 2 版之前,必須深入探討並瞭解這項重大影響。
最後,這裡的示範使用了 @scope
、巢狀和 @layer
的組合。這一切都令人興奮!