很早之前,就寫過一篇與原生嵌套相關的文章 -- CSS 即將支持嵌套,SASS/LESS 等預處理器已無用武之地?,彼時 CSS 原生嵌套還處於工作草案 Working Draft (WD) 階段,而今天(2023-09-02),CSS 原生嵌套 Nesting 終於成為了既定的規範! CSS 原生 ...
很早之前,就寫過一篇與原生嵌套相關的文章 -- CSS 即將支持嵌套,SASS/LESS 等預處理器已無用武之地?,彼時 CSS 原生嵌套還處於工作草案 Working Draft (WD) 階段,而今天(2023-09-02),CSS 原生嵌套 Nesting 終於成為了既定的規範!
CSS 原生嵌套語法
在之前,只有在 LESS、SASS 等預處理器中,我們才能使用嵌套的寫法,像是這樣:
div {
& > p {
color: red;
}
&:hover {
color: yellow;
}
}
從 Chrome 112 開始,原生 CSS 也可以使用嵌套語法了。
其語法規則大致如下:
parentRule {
/* parent rule style properties */
& childRule {
/* child rule style properties */
}
}
CSS 原生嵌套語法能力邊界
大部分同學對嵌套應該還是非常熟悉的,下麵我們一起看看,CSS 原生嵌套的能力邊界,語法支持範圍。
支持嵌套,並且支持多層嵌套
這個很好理解,直接看 DEMO:
<div class="g-container">
<h3 class="g-h3">CSS
<span class="g-span">Nesting</span>
</h3>
</div>
div {
border: 1px solid #000;
.g-h3 {
color: red;
.g-span {
color: blue;
}
}
}
效果如下:
當然,這裡有個值得註意的點。如果我們不使用具體的 ClassName,而是使用標簽名稱選擇器,像是這樣:
div {
border: 1px solid #000;
h3 {
color: red;
span {
color: blue;
}
}
}
嵌套規則是不會生效的,此時,我們需要在標簽名稱選擇器前,加上 &
符合:
div {
border: 1px solid #000;
& h3 {
color: red;
& span {
color: blue;
}
}
}
與 SASS 等類似,&
符號在嵌套中,也表示嵌套的父選擇器本身,因此,上面兩個嵌套選擇器最終的表達式實則為:
div h3 { color: red }
;div h3 span { color blue }
;
在嵌套中使用偽元素和偽類
直接上代碼,這個也是傳統 CSS 預處理器支持的內容:
div {
/* ... */
&:hover {
color: red;
}
&:is(.content, footer) {
padding: 16px;
}
&::before {
content: "";
/* ... */
}
}
上述代碼中,我們能夠在嵌套中使用偽類、偽元素。
在嵌套中使用媒體查詢
這個就比較有意思了,我們甚至可以在嵌套中,使用媒體查詢語法。
<div class="g-container">
<h3>CSS Nesting without @media</h3>
</div>
<div class="g-container media">
<h3>CSS Nesting with @media</h3>
</div>
.media {
@media (min-width: 600px) {
& h3 {
color: red;
}
}
}
此時,下方帶有 .media
class 的容器,在視口寬度大於 600px
的時候,設置 color: red
。
效果如下:
完整的 DEMO,你可以戳這裡試一下:CodePen Demo -- CSS Nesting Demo
在嵌套中嵌套自身
哈?什麼是在嵌套中嵌套自身?
其實也很好理解,也就是 &
符號的時候,上面提到了,&
符號在嵌套中,也表示嵌套的父選擇器本身,因此,我們還可以有這樣的寫法:
div {
& h2 & {
/* 表示 div h2 div {} */
}
}
這種寫法也是允許的,我們只需要將 &
替換成 div
即可,此時表示 div h2 div {}
。
總結一下
總結而言,CSS 原生的嵌套功能相當強大,基本是傳統預處理器的平替。使用嵌套規則的好處在於:
- 更加易讀和易維護,嵌套幫助我們編寫更易於維護的 CSS,基於嵌套,我們可以更好的控制樣式的作用域
- 更少的代碼,嵌套幫助我們編寫更少的代碼,因為我們不需要一遍又一遍地重覆父選擇器
隨著相容性的鋪開,慢慢地,我們可以嘗試真正運用它們到實際代碼中。
最後
好了,本文到此結束,希望對你有幫助