巢狀 CSS 樣式規則可讓樣式表更有條理、更容易閱讀及維護。
總覽
瞭解選取器後,您可能會想知道如何在樣式表內更妥善地整理選取器。假設您要為網站「功能」部分中的項目套用樣式,使用巢狀結構時,您可以將這些樣式分組到 .feature 規則中,如下所示:
.feature {
  button {
    color: blue;
  }
  .link {
    color: red;
  }
  .text {
    font-size: 1.3em;
  }
}
這與分別編寫每個樣式相同:
.feature button {
  color: blue;
}
.feature .link {
   color: red;
}
.feature .text {
   font-size: 1.3em;
}
巢狀結構可視需要深入多個層級。
.feature {
  .heading {
    color: blue;
    a {
      color: green;
    }
  }
}
分組及建立關係
巢狀結構可讓您更簡潔地分組,並建立樣式規則之間的關係。
根據預設,巢狀規則會以後代組合子的形式與外部規則相關。使用巢狀規則的選取器變更關係。
/* targets headings that are siblings of the .feature element and come immediately after it */
.feature {
  + .heading {
    color: blue;
  }
/* targets all paragraphs that are direct children of the .feature element */
  > p {
    font-size: 1.3em;
  }
}
使用 & 選取器定義明確關係
您也可以使用 & 選取器,在巢狀樣式規則中更明確地指定樣式。請將 & 視為代表父項選取器的符號。
.feature {
 & button {
    color: blue;
  }
}
這相當於以下列方式編寫樣式:
.feature button {
  color: blue;
}
何時需要 &
如果沒有 &,巢狀選取器會是父項選取器的後代選取器。如要形成複合選取器,& 必須。
.feature {
  &:last-child {
    /* Selects the .feature element that is the :last-child, equivalent to .feature:last-child */
  }
   
  & :last-child {
    /* Selects the :last-child inside of a .feature element, equivalent to .feature :last-child */
  }
  &.highlight {
    /* Selects .feature elements that also have a .highlight class, equivalent to .feature.highlight */
  }
  & .highlight {
     /* Selects elements inside of the .feature element with the class .highlight, equivalent to .feature .highlight */
  }
}
您也可以變更內容,並將 & 選取器放在子項選取器的結尾,或放在子項選取器的兩側。
/* Targets buttons with an adjacent sibling button */
button {
  & + & {
    /* … */
  }
}
img {
  .my-component & {
    /* styles for images inside of `.my-component` ... */
  }
}
在最後一個範例中,我們為 .my-component 類別的元素內圖片新增樣式。如果您正在處理的專案無法在元素中新增 class 或 id,這項功能就非常實用。
巢狀結構和精細設定
與 :is() 類似,巢狀選取器會採用父項選取器清單中特異性最高的選取器特異性。
#main-header,
.intro {
  & a {
    color: green;
  }
}
.intro a {
  color: blue;
}
第一條規則會指定 #main-header 和 .intro 元素內的所有連結,並將這些連結設為綠色。
第二條規則會嘗試覆寫這項設定,將 .intro 元素內的連結設為藍色。
如果查看每條規則的明確性,就能瞭解為何這項做法無效。
/* equivalent to :is(#main-header, .intro) a with a specificity of (1, 0, 1) */
#main-header,
.intro {
  & a {
    color: green;
  }
}
/* lower specificity of (0, 1, 1) */
.intro a {
  color: blue;
}
由於第一個規則的選取器清單中含有 id,且巢狀規則會採用選取器中最高特異性的選取器,因此第一個規則的特異性高於第二個規則。即使 a 元素不在含有 #main-header 選擇器的元素內,連結也會顯示為綠色。
巢狀結構無效
與 :is() 類似,巢狀選取器無法代表虛擬元素。
blockquote, blockquote::before, blockquote::after {
  color: navy;
  & {
    border: 1px solid navy;
  }
}
您會預期 blockquote 和其虛擬元素都有 navy 色彩的文字和邊框,但事實並非如此。由於 & 選擇器無法代表虛擬元素,因此巢狀邊框樣式只會套用至 blockquote。
使用 & 和型別選取器建立複合選取器時,型別選取器必須放在最前面,且兩者之間不得有任何空白。
/* valid css nesting */
.feature {
  p& {
    font-weight: bold;
  }
}
/* invalid css nesting */
.feature {
  &p {
    font-weight: bold;
  }
}
這項規則可讓 CSS 巢狀結構與 Sass 等前置處理工具搭配運作。在 Sass 中,寫入 &p 會將父項選取器附加至巢狀類型選取器,結果會是 .featurep。
巢狀 at 規則
CSS 條件式群組規則 (例如 @container、@media、@supports 和 @layer) 也可以巢狀化。
.feature {
  @media (min-width: 40em) {
    /* ... */
  }
  @container (inline-size > 900px) {
    /* ... */
  }
}
.feature {
  @supports (display: grid) {
    /* ... */
  }
}
.feature {
  @layer component {
    h2 {
      /* ... */
    }
  }
}
隨堂測驗
使用 CSS Nesting 時,& 選取器代表什麼?
巢狀結構最多只能有兩層。
哪些 at 規則可以巢狀化?
@media@container@import@supports@layer