👓

CSSにif文が追加されるらしい

2024/07/11に公開

CSSワーキンググループ(CSSWG)が
CSS Values Module Level 5仕様にif()条件を追加することを決定したそうです。
わりと革命的な気がして、驚いたのでzennにメモを残すことにします。

まだ提案が承認されたばかりという段階で、
今後W3CのCSSワーキンググループが仕様策定に取り組むこととなります。
これが完全に実現するまでには、まだしばらく時間がかかりそうですが、
未来のCSSスタイリングを大きく変える可能性のある仕様として、大きな注目を集めそうです。

https://css-tricks.com/if-css-gets-inline-conditionals/

構文:上記サイトの記事要約

<if()> = if( <container-query>, [<declaration-value>]{1, 2} )
  • 値をネストして複数のブランチを生成することができます。
  • 3番目の引数が指定されていない場合は、空のトークン ストリームと同等になります。

これらはすべて現時点では概念的なものであり、確定したものではありません。
CSSWG がこの機能に取り組むにつれて、状況は変化する可能性があります。
しかし、現状では、条件を指定して、宣言された 2 つのスタイルのうち
1つを設定するというアイデアが中心のようです。
1つは「デフォルト」スタイル、もう 1つは一致した場合に「更新された」スタイルになります。

.element {
  background-color:
    /* If the style declares the following custom property: */
    if(style(--variant: success),
      var(--color-green-50), /* Matched condition */
      var(--color-blue-50);  /* Default style */
    );
}

この場合、--variantというカスタムプロパティがsuccessに設定されているかどうかを確認し、

  • --variantがsuccessに設定されている場合、その値を--color-green-50(緑色の値)に設定する。
  • --variantがsuccessに設定されていない場合、その値を--color-blue-50(青色の値)に設定する。

デフォルトのスタイルはオプションなので、読みやすさを少し向上させるために省略できる場合もあります。

.element {
  background-color:
    /* If the style declares the following custom property: */
    if(style(--variant: success),
      var(--color-green-50) /* Matched condition */
    );
}

上の構文定義では、一致した条件と、条件内に条件をネストできるデフォルトのスタイルに加えて、
3番目の引数をサポートできることが示されています。

background-color: if(
  style(--variant: success), var(--color-success-60), 
    if(style(--variant: warning), var(--color-warning-60), 
      if(style(--variant: danger), var(--color-danger-60), 
        if(style(--variant: primary), var(--color-primary)
      )
    ),
  )
);

複雑なネストが可能で、
それをさらに簡略化するために以下のようなフラットな構造になる構文を提案しています。

<if()> = if( 
  [ <container-query>, [<declaration-value>]{2}  ]#{0, },
  <container-query>, [<declaration-value>]{1, 2} 
)

言い換えれば、ネストされた条件は初期条件の外側で宣言できるため、はるかにフラットです。
同じ概念ですが、構文が簡略化されます。

background-color: if(
  style(--variant: success), var(--color-success-60), 
  style(--variant: warning), var(--color-warning-60),
  style(--variant: danger), var(--color-danger-60), 
  style(--variant: primary), var(--color-primary)
);

1つのステートメントを別のステートメント内に含めるのではなく
すべての一致する条件を1つのステートメントにまとめることができます。
(if()文の中に複数の条件を含めることができる)

すべてスタイル・クエリに関係

要素のスタイルをクエリすることで、if() 条件に一致させようとしています。
寸法を問い合わせるための対応する size() 関数はありません

  • コンテナ・クエリは暗黙的にサイズを想定しています
.element {
  background: var(--color-primary);

  /* Condition */
  @container parent (width >= 60ch) {
    /* Applied styles */
    background: var(--color-success-60);
  }
}

また、コンテナ・クエリは、代わりにstyle()関数を呼び出すと、スタイル・クエリになります。

.element {
  background: orangered;

  /* Condition */
  @container parent style(--variant: success) {
    /* Applied styles */
    background: dodgerblue;
  }
}

スタイル・クエリーは、if()の文脈で捉えると、より理にかなったものになります。
if()がなければ、スタイル・クエリーの一般的な有用性を疑うのは簡単です。
しかし、このように考えてみると、
スタイル・クエリはコンテナ・クエリだけにとどまらない、
もっと大きな絵の一部であることは明らかです。

if()構文には、まだまだ解明すべきことがたくさんあります。
最終的にどうなるかはまだ未定です。

Discussion