我們最喜愛的其中一項 CSS 預先處理工具功能現已內建在程式語言中:巢狀樣式規則。
在建立巢狀結構之前,您必須明確宣告每個選取器,與其他選取條件分開。這會導致重複、樣式表大量和撰寫不整的內容。
.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
檢查巢狀選取器剖析功能。
使用巢狀結構:
html {
.has-nesting {
display: block;
}
.no-nesting {
display: none;
}
}
使用 @supports
:
@supports (selector(&)) {
/* nesting parsing available */
}
我的同事 Bramus 以超棒的 Codepen 介紹這項策略。
使用 Chrome 開發人員工具偵錯
目前的開發人員工具對巢狀結構的支援最少。目前,您會發現「Styles」窗格中會如預期呈現樣式,但還不支援追蹤巢狀結構及其完整的選取器內容。因此我們在設計和計畫 開誠佈公
Chrome 113 計劃進一步支援 CSS 巢狀結構。我們日後會再發佈相關消息,敬請密切注意。
日後規劃
CSS Nesting 目前為第 1 版。 第 2 版將推出更多語法糖,而且可能較少用於記憶的規則。巢狀結構的剖析要求數量很多,因此是不受限製或難以處理的棘手時刻。
巢狀結構是 CSS 語言的一大強化項目。它也對 CSS 架構方面的所有層面造成影響如果要有效指定版本 2,您必須先深入瞭解並理解這種巨大的影響。
最後的一項概念是此示範同時使用 @scope
、巢狀結構和 @layer
。真是令人興奮!