協助挑選 CSS 巢狀結構的語法

我們需要您的協助,決定要將哪個語法納入候選規格。

Adam Argyle
Adam Argyle
Miriam Suzanne
Miriam Suzanne

CSS 巢狀結構是方便的語法新增功能,可讓您在規則集內新增 CSS。如果您曾使用過 SCSSLessStylus,那麼您肯定看過以下幾種版本:

.nesting {
  color: hotpink;

  > .is {
    color: rebeccapurple;

    > .awesome {
      color: deeppink;
    }
  }
}

經過預處理器編譯為一般 CSS 後,就會變成以下的一般 CSS:

.nesting {
  color: hotpink;
}

.nesting > .is {
  color: rebeccapurple;
}

.nesting > .is > .awesome {
  color: deeppink;
}

我們正在積極考慮這個語法的官方 CSS 版本,但目前有兩種偏好設定,我們希望能藉由社群的協助來解決這個問題。本文其餘部分將介紹語法選項,讓您在結尾時能瞭解如何填寫問卷。

為什麼上述的巢狀結構示例無法用於 CSS 巢狀結構的語法?

以下是無法使用最常見巢狀語法的幾個原因:

  1. 不清晰的剖析
    部分巢狀選取器可以完全看起來像屬性和前置處理器,並在建構期間解析及管理這些屬性和前置處理器。瀏覽器引擎不會提供相同的操作選項,因此選擇器絕不能以鬆散的方式解讀。

  2. 前置處理器剖析衝突
    CSS 巢狀處理方式不應破壞前置處理器或現有的開發人員巢狀處理工作流程。這會對這些生態系統和社群造成干擾,也缺乏同理心。

  3. 等待 :is()
    基本巢狀結構不需要 :is(),但複雜的巢狀結構需要。如要簡單瞭解挑選器清單和巢狀結構,請參閱範例 3。假設選取器清單位於選取器中間,而非開頭,在這種情況下,您必須使用 :is() 才能將選取器分組至另一個選取器中間。

比較項目總覽

我們希望 CSS 巢狀結構正確無誤,因此我們會將社群納入其中。以下各節將說明我們正在評估的三種可能版本。接著,我們會介紹一些用途範例供您比較,最後會進行簡短的問卷調查,詢問您最喜歡哪一種用途。

方法 1:@nest

這是 CSS 巢狀結構 1 中目前指定的語法。它提供一種方便的方式,可透過 & 啟動新的巢狀選取器,巢狀附加樣式。它也提供 @nest,可用於將 & 內容放置在新選取器的任何位置,例如不只是附加主題時。這項方法雖然靈活且簡單,但您必須記住 @nest&,這取決於您的用途。

選項 2:@nest restricted

這是較嚴格的替代方案,可減少記住兩個巢狀方法的費用。這個受限制的語法只允許在 @nest 之後進行巢狀結構,因此沒有只附加的方便模式。移除選擇的模糊性,建立一個好記的巢狀方式,但犧牲了簡潔性,以便遵循慣例。

方法 3:使用括號

為了避免 @nest 提案涉及重複的語法或額外的雜亂,Miriam SuzanneElika Etemad 提出了替代語法,改為採用額外的大括號。這樣一來,語法就會更清楚,只需額外加入兩個字元,而且沒有新的 at-rule。您也可以依據所需的巢狀類型,將巢狀規則分組,藉此簡化多個類似的巢狀選取器。

範例 1 - 直接巢狀

@nest

.foo {
  color: #111;

  & .bar {
    color: #eee;
  }
}

@nest always

.foo {
  color: #111;

  @nest & .bar {
    color: #eee;
  }
}

括號

.foo {
  color: #111;

  {
    & .bar {
      color: #eee;
    }
  }
}

等效 CSS

.foo {
  color: #111;
}

.foo .bar {
  color: #eee;
}

範例 2:複合巢狀結構

@nest

.foo {
  color: blue;

  &.bar {
    color: red;
  }
}

@nest always

.foo {
  color: blue;

  @nest &.bar {
    color: red;
  }
}

括號

.foo {
  color: blue;

  {
    &.bar {
      color: red;
    }
  }
}

等效 CSS

.foo {
  color: blue;
}

.foo.bar {
  color: red;
}

範例 3 - 挑選器清單和巢狀結構

@nest

.foo, .bar {
  color: blue;

  & + .baz,
  &.qux {
    color: red;
  }
}

@nest always

.foo, .bar {
  color: blue;

  @nest & + .baz,
  &.qux {
    color: red;
  }
}

括號

.foo, .bar {
  color: blue;

  {
    & + .baz,
    &.qux {
      color: red;
    }
  }
}

等效 CSS

.foo, .bar {
  color: blue;
}

:is(.foo, .bar) + .baz,
:is(.foo, .bar).qux {
  color: red;
}

示例 4 - 多個層級

@nest

figure {
  margin: 0;

  & > figcaption {
    background: lightgray;

    & > p {
      font-size: .9rem;
    }
  }
}

@nest always

figure {
  margin: 0;

  @nest & > figcaption {
    background: lightgray;

    @nest & > p {
      font-size: .9rem;
    }
  }
}

括號

figure {
  margin: 0;

  {
    & > figcaption {
      background: lightgray;

      {
        & > p {
          font-size: .9rem;
        }
      }
    }
  }
}

等效 CSS

figure {
  margin: 0;
}

figure > figcaption {
  background: hsl(0 0% 0% / 50%);
}

figure > figcaption > p {
  font-size: .9rem;
}

示例 5 - 父項巢狀或主體變更

@nest

.foo {
  color: red;

  @nest .parent & {
    color: blue;
  }
}

@nest always

.foo {
  color: red;

  @nest .parent & {
    color: blue;
  }
}

括號

.foo {
  color: red;

  {
    .parent & {
      color: blue;
    }
  }
}

等效 CSS

.foo {
  color: red;
}

.parent .foo {
  color: blue;
}

範例 6 - 混合直接和父項巢狀

@nest

.foo {
  color: blue;

  @nest .bar & {
    color: red;

    &.baz {
      color: green;
    }
  }
}

@nest always

.foo {
  color: blue;

  @nest .bar & {
    color: red;

    @nest &.baz {
      color: green;
    }
  }
}

括號

.foo {
  color: blue;

  {
    .bar & {
      color: red;

      {
        &.baz {
          color: green;
        }
      }
    }
  }
}

等效 CSS

.foo {
  color: blue;
}

.bar .foo {
  color: red;
}

.bar .foo.baz {
  color: green;
}

範例 7 - 媒體查詢巢狀結構

@nest

.foo {
  display: grid;

  @media (width => 30em) {
    grid-auto-flow: column;
  }
}

或明確 / 延伸

.foo {
  display: grid;

  @media (width => 30em) {
    & {
      grid-auto-flow: column;
    }
  }
}

@nest always (一律明確)

.foo {
  display: grid;

  @media (width => 30em) {
    @nest & {
      grid-auto-flow: column;
    }
  }
}

括號

.foo {
  display: grid;

  @media (width => 30em) {
    grid-auto-flow: column;
  }
}

或明確 / 延伸

.foo {
  display: grid;

  @media (width => 30em) {
    & {
      grid-auto-flow: column;
    }
  }
}

等效 CSS

.foo {
  display: grid;
}

@media (width => 30em) {
  .foo {
    grid-auto-flow: column;
  }
}

範例 8 - 巢狀群組

@nest

fieldset {
  border-radius: 10px;

  &:focus-within {
    border-color: hotpink;
  }

  & > legend {
    font-size: .9em;
  }

  & > div {
    & + div {
      margin-block-start: 2ch;
    }

    & > label {
      line-height: 1.5;
    }
  }
}

@nest always

fieldset {
  border-radius: 10px;

  @nest &:focus-within {
    border-color: hotpink;
  }

  @nest & > legend {
    font-size: .9em;
  }

  @nest & > div {
    @nest & + div {
      margin-block-start: 2ch;
    }

    @nest & > label {
      line-height: 1.5;
    }
  }
}

括號

fieldset {
  border-radius: 10px;

  {
    &:focus-within {
      border-color: hotpink;
    }
  }

  > {
    legend {
      font-size: .9em;
    }

    div {
      + div {
        margin-block-start: 2ch;
      }

      > label {
        line-height: 1.5;
      }
    }}
  }
}

等效 CSS

fieldset {
  border-radius: 10px;
}

fieldset:focus-within {
  border-color: hotpink;
}

fieldset > legend {
  font-size: .9em;
}

fieldset > div + div {
  margin-block-start: 2ch;
}

fieldset > div > label {
  line-height: 1.5;
}

範例 9 - 複雜的巢狀群組「廚房水槽」

@nest

dialog {
  border: none;

  &::backdrop {
    backdrop-filter: blur(25px);
  }

  & > form {
    display: grid;

    & > :is(header, footer) {
      align-items: flex-start;
    }
  }

  @nest html:has(&[open]) {
    overflow: hidden;
  }
}

@nest always

dialog {
  border: none;

  @nest &::backdrop {
    backdrop-filter: blur(25px);
  }

  @nest & > form {
    display: grid;

    @nest & > :is(header, footer) {
      align-items: flex-start;
    }
  }

  @nest html:has(&[open]) {
    overflow: hidden;
  }
}

括號

dialog {
  border: none;

  {
    &::backdrop {
      backdrop-filter: blur(25px);
    }

    & > form {
      display: grid;

      {
        & > :is(header, footer) {
          align-items: flex-start;
        }
      }
    }
  }

  {
    html:has(&[open]) {
      overflow: hidden;
    }
  }
}

等效 CSS

dialog {
  border: none;
}

dialog::backdrop {
  backdrop-filter: blur(25px);
}

dialog > form {
  display: grid;
}

dialog > form > :is(header, footer) {
  align-items: flex-start;
}

html:has(dialog[open]) {
  overflow: hidden;
}

投票時間

希望您覺得這項比較公平,而且我們評估的語法選項也符合您的需求。請仔細查看這些選項,並在下方告訴我們你偏好哪一個。感謝您協助我們將 CSS 巢狀結構進化為我們都熟悉且喜愛的語法!

參加問卷調查!