CSS Nesting 巢狀語法

CSS 巢狀 (Nesting) 是現代 CSS 一項非常重要的功能。在過去,如果你想要撰寫具備層次關係的選擇器,你必須重複撰寫父選擇器的名稱,或者使用 Sass/Less 等預處理器。現在,原生 CSS 已經全面支援巢狀語法。

為什麼需要巢狀?

巢狀語法可以讓你的 CSS 程式碼結構與 HTML 結構更加一致,提高程式碼的可讀性與維護性,並減少重複撰寫選擇器的次數。

傳統寫法 vs 巢狀寫法

傳統寫法:

.card {
  padding: 20px;
  background: white;
}

.card .title {
  font-size: 1.5rem;
  color: #333;
}

.card .content {
  color: #666;
}

巢狀寫法:

.card {
  padding: 20px;
  background: white;

  .title {
    font-size: 1.5rem;
    color: #333;
  }

  .content {
    color: #666;
  }
}

使用 & 符號 (Parent Reference)

& 符號代表父選擇器。它常用於選取偽類(Pseudo-classes)或組合選擇器。

.button {
  background-color: blue;
  color: white;

  /* 代表 .button:hover */
  &:hover {
    background-color: darkblue;
  }

  /* 代表 .button.active */
  &.active {
    background-color: green;
  }
}

媒體查詢巢狀 (Nesting Media Queries)

你可以直接在選擇器內部撰寫媒體查詢,這讓響應式樣式的維護變得非常直覺。

.container {
  width: 100%;
  padding: 20px;

  @media (min-width: 768px) {
    width: 750px;
    margin: 0 auto;
  }
}

與預處理器 (Sass) 的差異

雖然 CSS 巢狀深受 Sass 啟發,但仍有一些技術上的差異:

  1. 解析方式:瀏覽器原生解析巢狀,不需要編譯過程。
  2. 語法細節:CSS 巢狀可以不使用 & 符號(只要內部選擇器是以 .#[ 等符號開頭),但 Sass 通常建議加上。
  3. 字串拼接:Sass 支援像 &-header 這樣的字串拼接,但 原生 CSS 不支援。你不能用 & 來組合出一個新的 class 名稱。
/* ❌ 在原生 CSS 中是無效的 */
.block {
  &-element {
    color: red;
  }
}

實務範例

導覽列組件

.navbar {
  display: flex;
  padding: 1rem;

  .nav-item {
    margin-right: 15px;

    a {
      text-decoration: none;
      color: #333;

      &:hover {
        color: blue;
        text-decoration: underline;
      }
    }
  }
}

瀏覽器支援度

原生 CSS 巢狀目前已獲得 Chrome 112+、Firefox 117+、Safari 16.5+ 以及 Edge 112+ 的全面支援。對於需要支援舊型瀏覽器的專案,建議仍使用 PostCSS 等工具進行降級處理。

適度使用巢狀可以增加可讀性,但應避免「巢狀過深」(建議不要超過 3 層),以免讓選擇器變得過於複雜且難以覆寫。