Sass 嵌套(Nested)
1. 前言
在企業(yè)的實(shí)際項(xiàng)目開發(fā)中,Sass 的嵌套可以說是非常非常有用的,它可以讓你的 CSS 代碼易于管理和維護(hù),看起來也比較清晰,這也是 Sass 中很基礎(chǔ)的一個(gè)知識點(diǎn),首先掌握這個(gè)至關(guān)重要!在此章節(jié)我們將學(xué)習(xí) Sass 嵌套中的嵌套規(guī)則、屬性嵌套、父選擇器和占位符選擇器。Sass 嵌套式一個(gè)很基礎(chǔ)也很簡單的語法,關(guān)鍵在于要多多練習(xí)使用!
2. 什么是嵌套?
在一般編寫 CSS 的時(shí)候呢,我們一遍一遍的編寫相同的選擇器去處理深層級的樣式,而 Sass 給你一種輕松的方式,你可以在一個(gè)樣式規(guī)則中直接編寫另一個(gè)樣式規(guī)則,而不是重復(fù)相同的選擇器,Sass 將自動組合內(nèi)外部的選擇器。
通俗點(diǎn)說就是:你可以在父選擇器的樣式中直接編寫子元素的樣式,同理你可以在一個(gè)子元素的樣式中再去編寫孫元素的樣式,可以一層一層的嵌套著去寫樣式。
3. 語法詳情
我們先舉一個(gè)簡單的例子體驗(yàn)下 Sass 的嵌套語法,看不懂沒關(guān)系,后面會逐一講解:
.father {
color: red;
.child {
color: green;
&:hover {
color: red;
}
&:active {
color: blue;
}
&-item {
color: orange;
}
}
}
這段 Sass 代碼最終會轉(zhuǎn)換為如下的 CSS 代碼:
.father {
color: red;
}
.father .child {
color: green;
}
.father .child:hover {
color: red;
}
.father .child:active {
color: blue;
}
.father .child-item {
color: orange;
}
4. 使用場景
一般來說 Sass 中的嵌套應(yīng)用于以下幾種場景:
- 樣式的嵌套
- 父選擇器
- 占位符選擇器
- 屬性嵌套
4.1 樣式的嵌套
Sass 允許將一套 CSS 樣式嵌套進(jìn)另一套樣式中,內(nèi)層的樣式將它外層的選擇器作為父選擇器,我們用編寫一個(gè)導(dǎo)航的樣式來舉例,假定我們的導(dǎo)航 nav 下面有 ul 標(biāo)簽,ul 標(biāo)簽下又有 li 標(biāo)簽,li 標(biāo)簽下呢又有 a 標(biāo)簽,下面我使用 Sass 來處理導(dǎo)航中的樣式:
nav {
width:200px;
background:white;
ul {
width:100%;
background:red;
li {
width:100%;
background:blue;
a {
color:green;
font-size:20px;
}
}
}
}
我們可以看到在上面的代碼中,我們在 nav 的樣式規(guī)則中,可以直接通過選擇器去編寫另外一套樣式規(guī)則,并且可以一直嵌套,這段代碼將會被編譯成如下的 CSS :
nav {
width: 200px;
background: white;
}
nav ul {
width: 100%;
background: red;
}
nav ul li {
width: 100%;
background: blue;
}
nav ul li a {
color: green;
font-size: 20px;
}
寫起來是不是方便很多,但使用嵌套的時(shí)候同時(shí)需要注意:
嵌套規(guī)則很有用很方便,但是你很難想象它實(shí)際會生成多少 CSS 語句,嵌套的越深,那么編譯為 CSS 的語句就越多,同時(shí)消耗的資源也會越多,所以開發(fā)者盡量不要嵌套特別深的層級!
4.1.1 嵌套選擇器列表 (Selector Lists)
嵌套規(guī)則可以很方便的處理選擇器列表,由逗號分隔的選擇器列表會被 Sass 組合到一個(gè)選擇器列表中,我們舉個(gè)例子看下:
.alert, .warning {
ul, p {
margin-right: 0;
margin-left: 0;
padding-bottom: 0;
}
}
上面這種寫法會被轉(zhuǎn)為如下的 CSS 代碼:
.alert ul, .alert p, .warning ul, .warning p {
margin-right: 0;
margin-left: 0;
padding-bottom: 0;
}
4.1.2 嵌套組合符選擇器 (Selector Combinators)
如果你對選擇符很陌生的話,一定要先看下什么是 CSS 選擇符
我們還可以嵌套使用帶有選擇符的選擇器,我們可以將選擇符放在外部選擇器的末尾,或者內(nèi)部選擇器的開始位置,這里我們舉一個(gè)官網(wǎng)的例子:
ul > {
li {
list-style-type: none;
}
}
h2 {
+ p {
border-top: 1px solid gray;
}
}
p {
~ {
span {
opacity: 0.8;
}
}
}
上面這種寫法會被轉(zhuǎn)換為如下的 CSS 代碼:
ul > li {
list-style-type: none;
}
h2 + p {
border-top: 1px solid gray;
}
p ~ span {
opacity: 0.8;
}
4.2 父選擇器 (Parent Selector)
父選擇器是 Sass 中一種特殊的選擇器,用于嵌套選擇器中,用來引用外部的選擇器;通俗的講就是,當(dāng)你使用嵌套的時(shí)候,可能你會需要使用到嵌套外層的父選擇器,比如為一個(gè)元素 添加偽類 (hover、active、before、after) 的時(shí)候,可以用 & 代表嵌套規(guī)則外層的父選擇器,我們舉個(gè)例子來更直觀的感受下:
a {
&:hover {
color:red;
}
&:active {
color:blue;
}
&:before {
content:'';
}
&:after {
content:'';
}
span {
&:hover {
color:green;
}
}
}
在上面的 Sass 代碼中我們編寫了幾個(gè)偽類,在編譯的時(shí)候 & 將會被替換為嵌套外層的父選擇器,有多層嵌套的話將會把父選擇器一級一級的傳遞下去,最終轉(zhuǎn)換為如下的 CSS 代碼:
a:hover {
color: red;
}
a:active {
color: blue;
}
a:before {
content: "";
}
a:after {
content: "";
}
a span:hover {
color: green;
}
4.2.1 添加后綴 (Adding Suffixes)
可以使用 & 向外部選擇器添加后綴,舉個(gè)例子看下:
.box {
width:100px;
&-head {
width:100%;
&-title {
color:red;
}
}
&-body {
width:100%;
}
&-footer {
width:100%;
}
}
上面這個(gè)例子將會轉(zhuǎn)換為如下的 CSS 代碼:
.box {
width: 100px;
}
.box-head {
width: 100%;
}
.box-head-title {
color: red;
}
.box-body {
width: 100%;
}
.box-footer {
width: 100%;
}
4.3 占位符選擇器 (Placeholder Selectors)
在 Sass 中這是一種特殊的選擇器,稱為 "占位符";它以 % 開頭,必須通過 @extend 指令調(diào)用,如果單獨(dú)使用的話是不會編譯到 CSS 中的,后面會講到 @extend 指令,這里我們先舉個(gè)簡單的例子感受一下:
%placeholder {
width:100px;
height:100px;
color:red;
&:hover {
color:blue;
}
}
.btn {
@extend %placeholder;
font-size: 18px;
}
.btn2 {
@extend %placeholder;
font-size: 16px;
}
請記住,占位符必須通過 @extend 指令調(diào)用才會轉(zhuǎn)換為如下的 CSS 代碼:
.btn2, .btn {
width: 100px;
height: 100px;
color: red;
}
.btn2:hover, .btn:hover {
color: blue;
}
.btn {
font-size: 18px;
}
.btn2 {
font-size: 16px;
}
4.4 屬性嵌套
當(dāng)我們在寫 CSS 樣式的時(shí)候,有些 CSS 屬性具有相同的命名空間 (namespace),比如定義字體樣式的屬性: font-size ; font-weight ; font-family ; 它們具有相同的命名空間 font 。再比如定義邊框樣式的屬性:border-radius ; border-color ; 它們具有相同的命名空間 border 。當(dāng)然還有很多其他這種的屬性,為了方便管理和避免重復(fù)輸入,Sass 允許將屬性嵌套在命名空間中,同時(shí)命名空間也可以具有自己的屬性值,我們舉例看一下:
.box {
border: {
radius: 5px;
color:red;
}
font: {
family:'YaHei';
size:18px;
weight:600;
}
margin: auto {
bottom: 10px;
top: 10px;
};
}
上面這種寫法將會被轉(zhuǎn)換為如下的 CSS 代碼:
.box {
border-radius: 5px;
border-color: red;
font-family: "YaHei";
font-size: 18px;
font-weight: 600;
margin: auto;
margin-bottom: 10px;
margin-top: 10px;
}
5. 實(shí)戰(zhàn)經(jīng)驗(yàn)
我們一起來看看在實(shí)際的項(xiàng)目開發(fā)中,Sass 嵌套是怎么應(yīng)用的;如下圖所示,這是一個(gè)比較常見的中后臺系統(tǒng)的頁面,我們使用 Sass 嵌套來編寫左側(cè)導(dǎo)航菜單的樣式。
這里左側(cè)導(dǎo)航我們用到了 element-ui 組件庫的導(dǎo)航組件,同時(shí)我們需要把左側(cè)導(dǎo)航的樣式修改為如圖所示的樣式,左側(cè)導(dǎo)航的主要 DOM 結(jié)構(gòu)是這樣的:
基于這樣的一個(gè) DOM 結(jié)構(gòu),在寫樣式的時(shí)候需要從 根節(jié)點(diǎn) .catalyst-gui-menu 開始來依次選擇子節(jié)點(diǎn)并編寫樣式,那么這里我們就可以直接使用 Sass 嵌套來編寫:
.catalyst-gui-menu {
width: 100%;
height: 100%;
.logo{
width: 100%;
height: 48px;
background: none;
color: #ffffff;
line-height: 48px;
display: flex;
align-items: center;
justify-content: center;
img {
width: 40px;
margin: 0px 8px 0px 0px;
}
span {
font-weight: 600;
font-size: 18px;
}
}
.menus {
width: 100%;
height: calc(100% - 48px);
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
padding-top: 16px;
}
.el-menu {
height: 100%;
.el-menu-item {
width:100%;
&:hover {
background: red;
}
}
}
}
可以看到我們編寫樣式的結(jié)構(gòu)就像 DOM 結(jié)構(gòu)一樣,是一層一層向下嵌套的,同時(shí)還使用了 & 為元素添加偽類,那么這段 Sass 代碼最終會轉(zhuǎn)換為如下的 CSS 代碼:
.catalyst-gui-menu {
width: 100%;
height: 100%;
}
.catalyst-gui-menu .logo {
width: 100%;
height: 48px;
background: none;
color: #ffffff;
line-height: 48px;
display: flex;
align-items: center;
justify-content: center;
}
.catalyst-gui-menu .logo img {
width: 40px;
margin: 0px 8px 0px 0px;
}
.catalyst-gui-menu .logo span {
font-weight: 600;
font-size: 18px;
}
.catalyst-gui-menu .menus {
width: 100%;
height: calc(100% - 48px);
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
padding-top: 16px;
}
.catalyst-gui-menu .el-menu {
height: 100%;
}
.catalyst-gui-menu .el-menu .el-menu-item {
width: 100%;
}
.catalyst-gui-menu .el-menu .el-menu-item:hover {
background: red;
}
可以對比兩段代碼看下,使用 Sass 嵌套寫出來的樣式代碼更有層次感,更易于維護(hù) (尤其是在企業(yè)級應(yīng)用,多人開發(fā)的時(shí)候),同時(shí)你不需要一遍一遍重復(fù)的去編寫當(dāng)前節(jié)點(diǎn)的父選擇器,所以說 Sass 嵌套在企業(yè)的前端項(xiàng)目開發(fā)中應(yīng)用特別廣泛,如果你接觸的公司的項(xiàng)目中有使用 Sass ,那么嵌套的寫法一定是項(xiàng)目中最普遍的!
6. 小結(jié)
本節(jié)內(nèi)容我們主要講了 Sass 中的嵌套規(guī)則,Sass 的嵌套是最基本也是最常用的功能,主要包括如下幾個(gè)重點(diǎn):
- 樣式的嵌套
- 基本的樣式嵌套
- 嵌套選擇器列表 (Selector Lists)
- 嵌套組合符選擇器 (Selector Combinators)
- 父選擇器
- 添加后綴 (Adding Suffixes)
- 占位符選擇器
- 屬性嵌套
你來根據(jù)下面這張圖來復(fù)習(xí)一下本節(jié)的內(nèi)容:
學(xué)會了 Sass 中的嵌套規(guī)則,快使用這種方式來改造一下你的 CSS 代碼吧~