これでよく分かる! 2023年、モダンCSSとUIの新しい機能のまとめ

2023年もCSSとUIの進化がすごいです!
先日開催されたGoogle I/O 2023から、各ブラウザにサポートされたモダンCSSの新機能をはじめ、まもなくサポートされる機能まで、CSSの新しい機能を紹介します。

コンテナクエリ、スタイルクエリ、ダイナミックビューポート単位、カスケードレイヤー、ネスト、三角関数、広色域のカラースペースなど、これからのWebサイトやスマホアプリのUI制作に役立ちます。

2023年、CSSとUIの新しい機能のまとめ

What's new in CSS and UI: I/O 2023 Edition
by Una Kravets, Bramus, Adam Argyle

下記は各ポイントを意訳したものです。
※元サイト様のライセンスに基づいて翻訳しています。

はじめに

ここ数ヵ月、WebのUIは黄金期が到来しています。
クロスブラウザに対応した新しいプラットフォーム機能が登場し、これまで以上に多くのWeb機能とカスタマイズ機能がサポートされるようになりました。

この記事では、最近登場したエキサイティングでインパクトのある機能を20個紹介したいと思います。

モダンCSSの新しいレスポンシブ

さっそく、CSSによるレスポンシブデザインの新機能を見てましょう。新しいプラットフォーム機能では、レスポンシブに対応したスタイル情報を持つコンポーネントで論理的なインターフェイスを構築したり、システム機能を活用してよりネイティブなUIを実現するインターフェイスを構築したり、ユーザー設定クエリでユーザーがカスタマイズ可能なデザインプロセスを可能にします。

コンテナクエリ

コンテナクエリでは、すべてのモダンブラウザにサポートされました。このクエリを使用すると、親要素のサイズとスタイルに応じて、その子要素に適用されるスタイルを適用できます。ちなみに、メディアクエリはビューポートの情報にしかアクセスできません。つまり、メディアクエリはページレイアウトのマクロビューでのみ機能します。そしてコンテナクエリは任意の数のレイアウトやレイアウト内のレイアウトをサポートできるより正確なツールと言えます。

たとえば、下記のデモページは受信トレイで、プライマリ受信トレイとお気に入りサイドバーは両方ともコンテナです。各メールは利用可能なスペースに応じてグリッドレイアウトが調整され、タイプスタンプを表示または非表示にします。これはページ内にまったく同じコンポーネントを使用して、異なるビューで表示されているだけです。コンテナクエリを使用する、利用可能なスペースに応じてグリッドレイアウトを調整することができます。

コンテナクエリがあるため、これらのコンポーネントのスタイルは動的です。ページのサイズやレイアウトを調整すると、コンポーネントはそれぞれに割り当てられたスペースに応じて最適化されます。サイドバーはスペースがあればトップバーになり、プライマリ受信トレイのようなレイアウトになるのが分かります。スペースが少ない場合は、どちらも圧縮されたデザインで表示されます。

See the Pen
Mail Demo - CQ
by web.dev (@web-dot-dev)
on CodePen.

コンテナクエリについて詳しくは、下記をご覧ください。

スタイルクエリ

コンテナクエリの仕様では、親コンテナのスタイル値もクエリすることができます。スタイルクエリは現在、Chrome 111で部分的に実装されており、CSSのカスタムプロパティを使用してコンテナのスタイルを適用できます。

下記のデモページでは、カスタムプロパティ値に格納された天気属性(晴れ・雨・曇りなど)を使用して、カードの背景とアイコンのスタイルを設定しています。

See the Pen
Style Queries Demo - Weather Cards
by web.dev (@web-dot-dev)
on CodePen.

スタイルクエリにCSSは、下記の通りです。

これはスタイルクエリの始まりに過ぎません。将来的にはカスタムプロパティ値が存在するかどうかを判断してコードの繰り返しを減らすためのブーリアンクエリや値の範囲に基づいてスタイルを適用するレンジクエリが現在検討されています。これらが実装されると、雨や曇りの確率をパーセント値で指定し、上記のデモページのようなスタイルを適用できるようになります。

スタイルクエリについて詳しくは、下記をご覧ください。

:hasセレクタ

CSSの強力で動的な機能といえば、:has()セレクタはモダンブラウザにサポートされたもっとも強力で新しい機能の一つです。:has()を使用すると、親要素に特定の子要素があるか、またはその子要素が特定の状態であるかに基づいてスタイルを適用することができます。つまり、実質的に親セレクタを持つことになります。

コンテナクエリに加えて:has()を使用すると、コンポーネントをさらにダイナミックにできます。下記は、スター要素を持つアイテムにグレーの背景が適用され、チェックボックスがオンになっているアイテムにはブルーの背景が適用されます。

デモのキャプチャ

ただし、このAPIは親の選択に限定されるものではありません。親に含まれる任意の子要素にもスタイルを適用できます。たとえば、アイテムにスター要素が存在する場合、タイトルは太字になります。これは.item:has(.star) .titleで実現できます。:has()セレクタを使用すると、親要素・子要素・兄弟要素にもアクセスできるため、非常に柔軟なAPIとなり、新しい使用方法がこれからも生まれるでしょう。

大規模なDOMツリーでのレンダリングパフォーマンスの低下を防ぐためには、この:has()セレクタのスコープをできるだけ厳密にすることをお勧めします。たとえば、:has()をルートのhtml要素で使用すると、ナビゲーションバーや小さなツリーのカード要素で一致をチェックするよりも遅くなります。

:has()について詳しくは、下記をご覧ください。

:nth-child()の「of S」構文

CSSのnth-child()は、より高度なn番目の子要素の選択ができるようになりました。新しいnth-child()構文では、ofという新しいキーワードが使用できるようになり、An+Bの既存の構文を使用しながら、より特定のサブセットを検索できます。

あるクラスに:nth-child(2)のように通常の構文を使用すると、ブラウザはこのクラスが適用された2番目の子要素を選択します。新しい構文:nth-child(2 of .special)を使用すると、最初にすべての.special要素をフィルタリングし、次にそのリスト内の2番目の子要素を選択します。

See the Pen
Record Wall (1)
by web.dev (@web-dot-dev)
on CodePen.

nth-child()について詳しくは、下記をご覧ください。

text-wrap: balance;

スタイルにロジックを埋め込むことができるのは、セレクタやスタイルクエリだけではありません。Chrome 114ではtext-wrapプロパティにbalanceという値を設定することで、見出しのバランスを調整できるようになりました。

テキストをバランスよく配置するために、ブラウザは行を増やさない最小の幅をバイナリ検索し、CSSの1ピクセル(表示ピクセルではない)で停止させます。バイナリ検索のステップをさらに最小限にするために、ブラウザは平均的な線幅の80%から開始します。

See the Pen
Balanced hero headline component
by web.dev (@web-dot-dev)
on CodePen.

コンテナの幅に応じて、テキストをバランスよく配置します。

See the Pen
Animated comparison of balanced and unbalanced headlines
by web.dev (@web-dot-dev)
on CodePen.

この機能は今すぐに試せますが、最大4行までのテキストしか機能しないことに注意することが重要です。そのため、タイトルや見出しには最適ですが、本文などの長いコンテンツにも向きません。

text-wrap: balance;について詳しくは、下記をご覧ください。

initial-letter

Webのタイポグラフィでもう一つ素晴らしい新機能が、initial-letterです。このCSSのプロパティは、インセットのドロップキャップのスタイルをより適切に制御できるようになります。

initial-letterプロパティを:first-letter疑似要素で使用すると、下記のデモページのように文字が占める行数に基づく文字の大きさを調整できます。「Lines」「Offset」のスライダーを動かしてみてください。

See the Pen
Explore CSS initial-letter
by web.dev (@web-dot-dev)
on CodePen.

initial-letterについて詳しくは、下記をご覧ください。

ダイナミックビューポート単位

今日、Web制作者が直面している共通の問題の一つは、スマホにおける正確で一貫性のあるフルビューポートのサイズ設定です。いわゆる「高さいっぱい」です。本来であれば100vhを「ビューポートと同じ高さ」で使用したいと思いますが、vhという単位はスマホでナビゲーションバーの格納などを考慮していないため、場合によっては長くなってしまいスクロールの原因となってしまいます。

Web制作者が直面している共通の問題

100vhだと、デバイスによって高さが異なる

この問題を解決するために、Webプラットフォームでは新しい単位が追加されました。

  • svh, svw: 小さなビューポートの高さと幅、最小のアクティブビューポートサイズを表します。
  • lvh, lvw: 大きなビューポートの高さと幅、最大のアクティブビューポートサイズを表します。
  • dvh, dvw: ダイナミック(動的な)ビューポートの高さと幅。

ダイナミックビューポート単位は、上部のアドレスや下部のタブバーなど追加のダイナミックブラウザのツールバーが表示されている場合と表示されていない場合に値が変化します。

新しいビューポート単位

新しいビューポート単位

ダイナミックビューポート単位では、仮想キーボードの存在が考慮されていないことに注意してください。Chrome 108からはmetaタグの設定でこの動作を変更できます。

ダイナミックビューポート単位について詳しくは、下記をご覧ください。

広色域のカラースペース

Webプラットフォームに新たに追加されたもう一つの重要な点が、鮮やかで美しい広色域のカラースペースです。広色域カラーが利用できるようになる前は、最新のデバイスで表示できる鮮やかな色の写真を撮影することはできましたが、ボタンやテキストの色、背景などをその鮮やかな色に合わせることはできませんでした。

現在Webプラットフォームに用意されているカラースペースは、REC2020、P3、XYZ、LAB、OKLAB、LCH、OKLCHなどさまざまなものがあります。HD Color Guideでは、新しいWebカラースペースやその他のカラースペースを紹介しています。

Webで使用できるカラースペース

Webで使用できるカラースペース

また、デベロッパーツールでもsRGBの範囲が終わり、より広いGamutの色域が始まるところを白い線によって表し、色域が広がっていることを確認することができます。

Chromeのデベロッパーツール

Chromeのデベロッパーツール

カラーに使用できるツールもたくさんあり、グラデーションの大幅な改善も見逃せません! Webで使用できる新しいカラーとグラデーションを試せる今までは全く新しいツールもあります。

サイトのキャプチャ

次世代のCSSグラデーションツールが美しすぎる! すべての新しい色空間を完全にサポート -CSS HD Gradients

color-mix()

拡張されたカラースペースを拡張するのがcolor-mix()関数です。この関数は、2つの色の値の混合をサポートし、混同させれう色のチャンネルに基づいて新しい値を作成します。混合するカラースペースは、結果に影響します。oklchのような知覚的なカラースペースで作業すると、srgbのようなカラースペースとは異なる色域が実行されます。

color-mix()関数は、長らく要望されていた機能(不透明な色の値を保持しながら透明度を追加する機能)も使用できます。たとえば、ブランドカラーを変数にし、異なる不透明度で色のバリエーションを作成することができます。ブランドカラーのブルーに10%の透明を混ぜると、90%の不透明なブランドカラーになります。このように、カラーシステムを素早く構築できることが分かります。

See the Pen
Color-mix pallete
by web.dev (@web-dot-dev)
on CodePen.

モダンCSSの基礎機能の強化

ユーザーに明確なメリットをもたらす新機能の構築もその一つですが、Chromeに導入された機能の多くはデベロッパーのエクスペリエンスを向上させ、より信頼性が高く組織化されたCSSアーキテクチャを構築するという目標を持っています。これらの機能には、CSSのネスト(入れ子)、カスケードレイヤー、スコープ付きのスタイル、三角関数、個々の変換プロパティなどがあります。

ネスト

ネスト(入れ子)はSassで多くのデベロッパーに愛され、長年CSSでも使用できるように要望されていたものです。ついにWebプラットフォームに上陸されることになりました。CSSのネストを使用することで、デベロッパーはより簡潔で、グループ化されたフォーマットでCSSを記述することができ、冗長性を減らすこともできます。

CSSのネストは、メディアクエリでも使用できます。つまり、コンテナクエリをネストできることを意味します。下記のCSSは、コンテナに十分な幅がある場合にカードは縦向きのレイアウトから横向きのレイアウトの変更されます。

flexのレイアウト調整は、コンテナのインラインスペースが480px以上の場合に発生します。ブラウザはこの条件が満たされたときに、そのスタイルを適用します。

CSSのネストについて詳しくは、下記をご覧ください。

カスケードレイヤー

デベロッパーのもう一つの悩みの種は、どのスタイルが他のスタイルよりも優先されるか一貫性を確保することです。その解決策として、CSSのカスケードレイヤーが登場しました。

CSSのカスケードレイヤーは、どのレイヤーが他のレイヤーより優先されるかをユーザーがコントロールできるようにすることで、この問題を解決します。

CSSのカスケードレイヤー

CSSのカスケードレイヤーについて詳しくは、下記をご覧ください。

スコープ付きスタイル

CSSのスコープ付きスタイルを使用すると、特定のスタイルが適用される境界を指定でき、CSSにネイティブな名前空間を作成できます。以前はサードパーティのスクリプトでクラスを名前変更するか、スタイルの衝突を防ぐために特定の命名規則に頼っていましたが、まもなく@scopeを使用できるようになります。

@scopeの使い方はたとえば、.title要素を.cardにスコープする場合は下記のように記述します。これでカード以外に使用する.title要素のスタイルと競合することを防ぐことができます。

下記のデモページでは、スコープ付きスタイルの@scope@layerを確認できます。

See the Pen
Nesting Test Ground
by web.dev (@web-dot-dev)
on CodePen.

CSSのスコープ付きスタイルについて詳しくは、下記をご覧ください。

三角関数

CSSの基礎機能を支えるもう一つのピースは、既存の数学関数に追加された三角関数です。すべてのモダンブラウザでサポートされており、Webプラットフォーム上でより有機的なレイアウトを作成できるようになりました。好例の一つは、下記デモの放射状メニューです。sin()cos()関数を使用してデザインとアニメーションが可能になりました。

デモでは、ドットが中心点の周りを回転します。各ドットは外側に移動するのではなく、X軸とY軸で移動しています。X軸とY軸の距離は、それぞれ--anglesin()cos()関数によって決定されます。

See the Pen
CSS Trigonometric Functions: cos() and sin(): dots on a circle
by web.dev (@web-dot-dev)
on CodePen.

CSSの三角関数について詳しくは、下記をご覧ください。

個々の変換プロパティ

デベロッパーの人間工学は、個々の変換関数によって改善され続けています。前回I/Oを開催して以来、すべてのモダンブラウザで個々のトランスフォームが安定しました。

以前は、UI要素を拡大縮小・回転・平行移動させるサブ関数を適用するには、transform関数に依存していました。これには多くの繰り返しがあり、特にアニメーションの異なるタイミングで複数のトランスフォームを適用する場合にフラストレーションを感じていました。

transformの種類を分離し、個別に適用することで、CSSアニメーションにすべての詳細を含めることができるようになりました。

この機能により、translate, rotate, scaleによる移動・回転・スケールの変更がアニメーション中にさまざまな時間にさまざまな変化率を同時に発生できるようになります。

個々の変換プロパティについて詳しくは、下記をご覧ください。

カスタマイズ可能なコンポーネント

Webプラットフォームを通じてデベロッパーの主要なニーズを確実に解決するために、わたし達はOpenUIコミュニティグループと協力して、3つの解決策を特定しました。

  1. イベントハンドラ、宣言的なDOM構造、アクセシブルなデフォルトを備えた組み込みのポップアップ機能。
  2. アンカーの位置決めを可能にするために、2つの要素を互いに結びつけるCSS API。
  3. select内のコンテンツのスタイルを設定するために、カスタマイズ可能なドロップダウンメニューのコンポーネント。

ポップオーバー

popover APIは、要素に次のような機能を実現します。

  • トップレイヤーのサポートにより、z-indexを管理する必要はなくなります。ポップオーバーやダイアログを表示すると、その要素はページ最上部の特別なレイヤーになります。
  • 自動ポップオーバーでは閉じる動作が自動で設定できるため、要素の外側をクリックすると、ポップオーバーは閉じられ、アクセシビリティツリーから取り除かれ、フォーカスも適切に管理されます。
  • ポップオーバーのターゲットとポップオーバー自体の結合組織に対するデフォルトのアクセシビリティ。

これらの機能が備わっているため、これらの状態を管理するJavaScriptの記述が少なくなることを意味します。

ポップオーバー

ポップオーバー

ポップオーバーのDOM構造は宣言型で、ポップオーバー要素にidpopover属性を与えるだけです。次に、そのidに記述した値をpopovertargetに記述します。

popover属性は、popover=autoの短縮形です。popover=autoを持つ要素は、開いたときに他のポップオーバーを強制的に閉じ、開いたときにフォーカスを受け取り、ライトディスミスをすることができます。逆にpopover=manualの要素は、他の要素を強制的に閉じず、すぐにフォーカスを受けず、ライトディスミスをしません。そのため、閉じる動作をするトグルなどで閉じます。

See the Pen
Basic manual popover with close button
by web.dev (@web-dot-dev)
on CodePen.

popoverについて詳しくは、下記をご覧ください。

アンカーのポジショニング

ポップオーバーはダイアログやツールチップなど、特定の要素に固定する必要がある要素でよく使用されます。このイベントの例を考えてみましょう。カレンダーがイベントをクリックすると、クリックしたイベントの近くにダイアログが表示されます。カレンダーの項目はアンカーで、ポップオーバーはイベントの詳細を表示するダイアログです。

anchor()関数で中央は位置のツールチップを作成、アンカーからの幅を使用して、ツールチップをアンカーのx位置の50%に配置します。次に既存の位置決め値を使用して残りの配置スタイルを適用します。

しかし、ポップオーバーの配置方法によっては、ポップオーバーがビューポートに収まらない場合があります。

ポップオーバーがビューポートに収まらない場合

ポップオーバーがビューポートに収まらない場合

これを解決するために、anchor positioning APIには、カスタマイズ可能なフォールバックポジションが用意されています。たとえば、top-then-bottomというフォールバックポジションを作成しておきます。ブラウザはツールチップを上部に配置しようとしてビューポートに収まらない場合は、これを使用してアンカー要素の下部に配置します。

実際の動作はデモページでご覧ください。

See the Pen
Toggletip Demo
by web.dev (@web-dot-dev)
on CodePen.

詳細に設定できるため、冗長になる可能性があります。しかし、ライブラリやデザインシステムがポジショニングのロジックを記述し、それをどこでも再利用することができます。

アンカーのポジショニングについて詳しくは、下記をご覧ください。

セレクトメニュー

ポップオーバーとアンカーのポジショニングの両方を使用して、完全にカスタマイズ可能なセレクトメニューを実装することができます。OpenUIのコミュニティグループはこれらのメニューの基本構造を調査し、メニュー内のコンテンツをカスタマイズできる方法を探しています。以下にその視覚的な例をご覧ください。

セレクトメニュー内のコンテンツをカスタマイズ

セレクトメニュー内のコンテンツをカスタマイズ

カレンダーのイベントに表示される色に対応したドットを実装するには、次のように記述します。

実際の動作はデモページでご覧ください。

See the Pen
Selectmenu demo
by web.dev (@web-dot-dev)
on CodePen.

個別のプロパティによるアニメーション

ポップオーバーをスムーズに表示・非表示するには、CSSで個別のプロパティをアニメーション化する方法が必要です。たとえば、トップレイヤーとの間のアニメーションやdisplay: none;との間のアニメーションなど、今まではアニメーション化が不可能だったプロパティです。

ポップオーバーやセレクトメニュー、さらにはダイアログやカスタムコンポーネントなど既存の要素に対して美しいトランジションを可能にする取り組みの一環として、ブラウザはこれらのアニメーションをサポートする新しい機能を有効にしました。

下記のデモでは、ポップオーバーを開いた状態に:popover-open、開く前の状態に@initialを使用してポップオーバーの表示・非表示をアニメーション化しています。これらをdisplayで動作させるためには、transitionプロパティに次のように記述します。

実際の動作はデモページでご覧ください。

See the Pen
Toolbar Popover Demo - Transition in and out, cleaner with nesting
by web.dev (@web-dot-dev)
on CodePen.

これは現在、実験的な機能で、@initial構文は変更される可能性があります。

displayのアニメーション化や@initialについて詳しくは、下記をご覧ください。

CSSによるインタラクション

CSSの新機能ツアーの最後の目的地、インタラクションについて説明します。

個別のプロパティによるアニメーション化についてはすでに説明しましたが、Chromeにはスクロール駆動のアニメーションやビューの遷移に関する非常にエキサイティングなAPIもあります。

スクロール駆動のアニメーション

スクロール駆動のアニメーションを使用すると、スクロールコンテナのスクロール位置に基づいてアニメーションの再生をコントロールできます。つまり、上下にスクロールするとアニメーションは前後にスクラブされます。さらにスクロール駆動のアニメーションでは、スクロールコンテナ内の要素の位置に基づいてアニメーションをコントロールできます。これにより、パララックスな背景画像やスクロールのプログレスバーやビューポートに表示されると表示される画像など、さまざまなエフェクトを実装することができます。

このAPIはJavaScriptクラスとCSSプロパティのセットをサポートしており、宣言型のスクロール駆動アニメーションを簡単にできます。

スクロールによるCSSアニメーションを実装するには、新しいプロパティ(scroll-timeline, view-timeline, animation-timeline)を使用します。JavaScriptのWebアニメーションAPIを利用するには、timelineオプションとしてScrollTimelineまたはViewTimelineインスタンスをElement.animate()に渡します。

これらの新しいAPIは既存のWebアニメーションのAPIやCSSアニメーションのAPIと連携して動作するため、既存のAPIの利点を活かすこともできます。その中には、メインスレッドからアニメーションを実行させる機能も含まれています。数行のコードを追加するだけで、メインスレッドからスクロールによって駆動する絹のように滑らかなアニメーションを実行できるようになりました。これほど素晴らしいことはないでしょう!

スクロール駆動のアニメーション

スクロール駆動のアニメーションについて詳しくは、下記をご覧ください。

ビューのトランジション

View Transition APIを使用すると、2つの状態間にアニメーションによるトランジションを作成しながら、DOMを1つのステップで簡単に変更できます。これはビュー間の単純なフェードである場合もありますが、ページ内の個々の要素がどのようにトランジションするかをコントロールすることもできます。

ビューのトランジションは、プログレスエンハンスメントとしても使用できます。何らかの方法でDOMを更新するコードをView Transition APIでラップし、この機能をサポートしていないブラウザ用にフォールバックを作成します。

トランジションがどのように見えるかは CSSによってコントロールできます。

この機能は、Maxi Ferreiraによるこの素晴らしいデモで実証されているように動画の再生などの他のページ インタラクションはビューのトランジションが発生している間も動作し続けます。

View Transition APIは現在、Chrome 111からシングルページアプリ(SPA)で動作します。複数ページアプリのサポートは、現在作業中です。詳しくは、the View Transitions APIをご覧ください。

終わりに

developer.chrome.comでは、CSSとHTMLの最新情報をお届けしています。また、Webランディングの詳細についてはI/Oビデオをチェックしてください。

sponsors

top of page

©2024 coliss