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