CSS ネストの構文の選択に関するヘルプ

競合する 2 つの構文は、どれを仕様候補に採用すべきかを判断する際にお客様の助けを必要としています。

Adam Argyle 氏
Adam Argyle
ミリアム・スザンヌ
Miriam Suzanne

CSS のネストは、ルールセット内に CSS を追加するための便利な構文の追加機能です。SCSSReduceStylus を使ったことがある方は、次のようないくつかのバリエーションを目にしていることでしょう。

.nesting {
  color: hotpink;

  > .is {
    color: rebeccapurple;

    > .awesome {
      color: deeppink;
    }
  }
}

これは、プリプロセッサによって通常の CSS にコンパイルされた後、次のような通常の CSS に変わります。

.nesting {
  color: hotpink;
}

.nesting > .is {
  color: rebeccapurple;
}

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

この構文の公式の CSS バージョンは検討の余地があります。YouTube では、コミュニティの協力により両者の結びつきを強めるようにしたいと考えています。この投稿の残りの部分では、構文オプションを紹介します。これにより、最後にアンケートに回答することができます。

上記のネスト例が CSS のネストの構文ではできないのはなぜですか?

最も一般的なネスト構文をそのまま使用できない理由はいくつかあります。

  1. 不明瞭な解析
    一部のネストされたセレクタは、プロパティやプリプロセッサとまったく同じように見える場合があり、ビルド時にそれらを解決して管理できます。ブラウザ エンジンのアフォーダンスは異なるため、セレクタを大まかに解釈しないようにする必要があります。

  2. プリプロセッサの解析の競合
    CSS のネスト方法によって、プリプロセッサが壊れることがないようにする必要があります、または既存のデベロッパーのネスト ワークフローが壊れないようにする必要があります。これは、こうしたエコシステムやコミュニティにとって混乱を招くものであり、配慮に欠ける可能性があります。

  3. :is() を待機しています
    基本的なネストでは :is() は必要ありませんが、より複雑なネストでは必要です。セレクタ リストとネストの概要については、例 3 をご覧ください。セレクタリストがセレクタの先頭ではなく中央にあったとします。その場合、別のセレクタの中間にあるセレクタをグループ化するために、:is() が必要です。

比較対象の概要

Google は CSS を適切にネストし、コミュニティを組み込んでいます。以下のセクションでは、評価中の 3 つのバージョンについて説明します。その後、いくつかの使用例を示して比較し、最後に簡単なアンケートで、全体的にどちらがお好みかをお尋ねします。

オプション 1: @nest

これは現在 CSS ネスト 1 で指定されている構文です。& で新しいネストされたセレクタを開始することで、追加スタイルをネストするのに便利です。また、単にサブジェクトを追加するだけの場合ではなく、新しいセレクタ内の任意の場所に & コンテキストを配置する方法として、@nest を提供しています。柔軟性が高く最小限に抑えられますが、ユースケースに応じて @nest または & を記憶する必要があります。

オプション 2: @nest を制限する

これはより厳密な代替手段であり、2 つのネスト方法を覚えるというコストの削減を目的としています。この制限付きの構文では、@nest の後にのみネストが許可されるため、便利な追加のみのパターンはありません。選択肢のあいまいさを取り除き、覚えやすいネストの方法を作成しますが、規則のために簡潔さを犠牲にしています。

オプション 3: 角括弧

@nest 提案に伴う二重構文や雑然とした構成を避けるために、Miriam SuzanneElika Etemad は、追加の中かっこを使用する代替構文を提案しました。これにより、構文が明確になり、文字が 2 つだけ追加され、新しいアットルールがなくなります。また、同様にネストされた複数のセレクタを簡素化するために、ネストされたルールを必要なネストの種類ごとにグループ化することもできます。

例 1 - 直接ネスト

@Nest

.foo {
  color: #111;

  & .bar {
    color: #eee;
  }
}

@nest は常に

.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 は常に

.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 は常に

.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 は常に

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 は常に

.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 は常に

.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 は常に(常に明示)

.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 は常に

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 は常に

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 のネストを、誰もが理解できる構文に進化させるためにご協力いただきありがとうございます。

アンケートに回答する