CSS とウェブ UI の最新情報: I/O 2024 のまとめ

ウェブ プラットフォームはイノベーションに満ちており、CSS とウェブ UI の機能がこのエキサイティングな進化の最前線にあります。ウェブ UI は黄金時代を迎えています。これまでにないペースで新しい CSS 機能がブラウザに実装され、美しく魅力的なウェブ エクスペリエンスを作成するための可能性が広がっています。このブログ投稿では、CSS の現状について詳しく説明し、Google I/O 2024 でライブで紹介された、ウェブ アプリケーションの構築方法を再定義する最も画期的な新機能についてご紹介します。

新しいインタラクティブなエクスペリエンス

ウェブ エクスペリエンスは、基本的にサイト運営者とユーザー間の呼び出しと応答です。そのため、質の高いユーザー インタラクションに投資することが非常に重要です。Google は、ウェブページ内の移動とウェブページ間の移動において、これまでウェブで実現できなかった機能を可能にする大きな改善に取り組んでいます。

スクロールドリブン アニメーション

Browser Support

  • Chrome: 115.
  • Edge: 115.
  • Firefox: behind a flag.
  • Safari: 26.

Source

名前のとおり、スクロール ドリブン アニメーション API を使用すると、スクロール オブザーバーやその他の重いスクリプトに依存することなく、動的なスクロールベースのアニメーションを作成できます。

スクロールドリブン アニメーションを作成する

プラットフォームで時間ベースのアニメーションが動作するのと同様に、スクローラーのスクロール進行状況を使用してアニメーションを開始、一時停止、逆再生できるようになりました。そのため、前方にスクロールするとアニメーションが進み、後方にスクロールすると逆方向に進みます。これにより、ビューポート内に出入りする要素を含む部分ページまたは全ページのビジュアル(スクロール テリングとも呼ばれます)を作成して、動的な視覚効果を実現できます。

スクロール連動アニメーションは、重要なコンテンツをハイライト表示したり、ストーリーをユーザーに伝えたり、ウェブページにダイナミックなタッチを加えたりするために使用できます。

スクロール駆動型アニメーションのビジュアル

ライブデモ

@keyframes appear {
  from {
    opacity: 0;
    scale: 0.8;
  }
  to {
    opacity: 1;
    scale: 1;
  }
}

img {
  animation: appear linear;
  animation-timeline: view();
  animation-range: entry 25% cover 50%;
}

上記のコードは、画像の不透明度とスケールを変更してビューポートに表示される簡単なアニメーションを定義しています。アニメーションはスクロール位置によって駆動されます。この効果を作成するには、まず CSS アニメーションを設定してから、animation-timeline を設定します。この場合、デフォルト値の view() 関数は、スクロールポート(この場合はビューポートでもある)に対する画像の相対位置を追跡します。

ブラウザのサポートとユーザー設定(特にユーザー補助機能)に留意することが重要です。したがって、@supports ルールを使用してブラウザがスクロール駆動アニメーションをサポートしているかどうかを確認し、スクロール駆動アニメーションを @media (prefers-reduced-motion: no-preference) などのユーザー設定クエリでラップして、ユーザーのモーション設定を尊重します。これらのチェックを行うことで、スタイルが機能し、アニメーションがユーザーにとって問題にならないことがわかります。

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    /* Apply scroll-driven animations here */
  }
}

スクロール駆動型アニメーションは、ページ全体を使ったスクロール テリング エクスペリエンスを意味することもありますが、ウェブアプリをスクロールするとヘッダーバーが最小化され、影が表示されるといった、より繊細なアニメーションを意味することもあります。

スクロール駆動型アニメーションのビジュアル

ライブデモ

@keyframes shrink-name {
  from {
    font-size: 2em;
  }
  to {
    font-size: 1.5em;
  }
}

@keyframes add-shadow {
  from {
    box-shadow: none;
  }
  to {
    box-shadow: 0 4px 2px -2px gray;
  }
}

header {
  animation: add-shadow linear both;
}

h2 {
  animation: shrink-name linear both;
}

header, h2 {
  animation-timeline: scroll();
  animation-range: 0 150px;
}

このデモでは、ヘッダー、テキスト、ナビゲーション バー、背景など、いくつかの異なるキーフレーム アニメーションを使用し、それぞれにスクロール駆動型アニメーションを適用しています。アニメーション スタイルはそれぞれ異なりますが、アニメーション タイムライン、最も近いスクローラー、アニメーション範囲(ページの上部から 150 ピクセル)はすべて同じです。

スクロール ドリブン アニメーションのパフォーマンス上のメリット

この組み込み API を使用すると、作成したカスタム スクリプトや追加のサードパーティ依存関係の組み込みなど、維持する必要があるコードの負担を軽減できます。また、さまざまなスクロール オブザーバーを送信する必要がなくなるため、パフォーマンスが大幅に向上します。これは、CSS で新しい API を直接使用しているか、JavaScript フックを使用しているかにかかわらず、スクロール駆動型アニメーションは、コンポジタでアニメーション化できるプロパティ(変換や不透明度など)をアニメーション化する際にメインスレッド外で動作するためです。

Tokopedia は最近、スクロール駆動型アニメーションを使用して、スクロールすると商品ナビゲーション バーが表示されるようにしました。この API を使用することで、コード管理とパフォーマンスの両面で大きなメリットが得られました。

スクロール駆動型アニメーションにより、Tokopedia のこのプロダクト ナビゲーション バーは、下にスクロールすると移動します。

「従来の JS スクロール イベントを使用した場合と比較して、コード行数を最大 80% 削減できました。また、スクロール中の平均 CPU 使用率が 50% から 2% に低下したことも確認できました。- Andy Wihalim 氏、Tokopedia シニア ソフトウェア エンジニア」

スクロール効果の未来

こうした効果によってウェブがさらに魅力的な場所になることは間違いありません。Google はすでに、次のステップについて検討しています。これには、新しいアニメーション タイムラインを使用するだけでなく、スクロール ポイントを使用してアニメーションの開始をトリガーする(スクロール トリガー アニメーションと呼ばれる)機能も含まれます。

今後、ブラウザにはさらに多くのスクロール機能が追加される予定です。次のデモでは、これらの将来の機能を組み合わせたものをご覧いただけます。CSS scroll-start-target を使用して選択ツール内の初期日時を設定し、JavaScript scrollsnapchange イベントを使用してヘッダーの日付を更新します。これにより、データをスナップされたイベントと簡単に同期できます。

Codepen でライブデモを見る

また、この機能を基に、JavaScript の scrollsnapchanging イベントを使用してピッカーをリアルタイムで更新することもできます。

これらの機能は現在、Canary でフラグの背後にのみ存在しますが、以前はプラットフォームで構築することが不可能または非常に困難だった機能をアンロックし、スクロールベースのインタラクションの可能性の未来を強調しています。

スクロール駆動アニメーションの概要については、Chrome for Developers YouTube チャンネルで公開された新しい動画シリーズをご覧ください。ここでは、Bramus Van Damme 氏によるスクロール駆動アニメーションの基本について学びます。この機能の仕組み、用語、さまざまな効果の作成方法、効果を組み合わせてリッチなエクスペリエンスを構築する方法などについて説明します。ぜひご覧ください。

遷移を表示する

ウェブページのアニメーション化という強力な新機能について説明しましたが、ページビューのアニメーション化によってシームレスなユーザー エクスペリエンスを実現するビュー トランジションという強力な新機能もあります。ビューの切り替えにより、ウェブに新たなレベルの流動性が導入され、単一ページ内の異なるビュー間、さらには異なるページ間でシームレスな切り替えを作成できるようになります。

Browser Support

  • Chrome: 111.
  • Edge: 111.
  • Firefox: 144.
  • Safari: 18.

Source

Airbnb は、スムーズでシームレスなウェブ ナビゲーション エクスペリエンスを実現するために、ビュー遷移を UI に統合するテストをすでに実施している企業の 1 つです。これには、リスティング エディタのサイドバーから、写真の編集やアメニティの追加まで、ユーザーがサイト内を移動しながらスムーズに行えるようにしました。

Airbnb で見られるような、同じドキュメント内のビューの切り替え。
ビュー間のビュー遷移を示す Maxwell Barvian のポートフォリオ。

全画面効果は美しくシームレスですが、この例のように、ユーザーの操作でリストビューが更新されるマイクロ インタラクションを作成することもできます。この効果は、ビューの切り替えで簡単に実現できます。

シングルページ アプリケーションでビュー遷移をすばやく有効にする方法は、document.startViewTransition を使用してインタラクションをラップし、遷移する各要素に view-transition-name を設定するだけです。インラインで設定するか、JavaScript を使用して DOM ノードを作成する際に動的に設定します。

デモのビジュアル

ライブデモ

document.querySelectorAll('.delete-btn').forEach(btn => {
  btn.addEventListener('click', () => {
    document.startViewTransition(() => {
      btn.closest('.card').remove();
    });
  })
});
/* Styles for the transition animation */
::view-transition-old(.card):only-child {
  animation: fade-out ease-out 0.5s;
}

遷移クラスを表示する

ビュー遷移名を使用すると、ビュー遷移にカスタム アニメーションを適用できますが、遷移する要素が多い場合は面倒になる可能性があります。今年最初のビュー遷移の新しいアップデートでは、この問題が簡素化され、カスタム アニメーションに適用できるビュー遷移クラスを作成できるようになりました。

Browser Support

  • Chrome: 125.
  • Edge: 125.
  • Firefox: 144.
  • Safari: 18.2.

Source

切り替え効果の種類を表示する

ビュー遷移のもう 1 つの大きな改善点は、ビュー遷移タイプのサポートです。ビュー遷移タイプは、ページビューとの間でアニメーションを行う際に、異なる種類の視覚的なビュー遷移が必要な場合に便利です。

Browser Support

  • Chrome: 125.
  • Edge: 125.
  • Firefox: 144.
  • Safari: 18.

Source

たとえば、ホームページからブログページに移動するアニメーションと、ブログページからホームページに戻るアニメーションを異なるものにしたい場合があります。また、この例のように、左から右、右から左へとページを切り替えることもできます。以前は、DOM にクラスを追加してスタイルを適用し、その後クラスを削除する必要がありました。View-transition-types を使用すると、新しいトランジションを開始する前に手動で古いトランジションをクリーンアップする必要がなくなり、ブラウザが自動的にクリーンアップを行います。

ページネーション デモの録画。タイプによって、使用するアニメーションが決まります。アクティブな遷移タイプのおかげで、スタイルシートでスタイルが分離されています。

document.startViewTransition 関数内で型を設定できるようになりました。この関数はオブジェクトを受け取るようになりました。update は DOM を更新するコールバック関数で、types は型を含む配列です。

document.startViewTransition({
  update: myUpdate,
  types: ['slide', 'forwards']
})

マルチページ ビューの切り替え

ウェブの強みは、その広大さです。多くのアプリケーションは、単一のページではなく、複数のページを含む堅牢なタペストリーです。そこで、Chromium 126 でマルチページ アプリケーションのドキュメント間のビュー遷移のサポートを開始することをお知らせします。

Browser Support

  • Chrome: 126.
  • Edge: 126.
  • Firefox: not supported.
  • Safari: 18.2.

Source

この新しいクロスドキュメント機能セットには、同一オリジン内で動作するウェブ エクスペリエンスが含まれます(web.dev から web.dev/blog への移動など)。ただし、web.dev から blog.web.dev や google.com などの別のドメインへの移動など、クロスオリジンでの移動は含まれません。

同じドキュメント内のビュー遷移との主な違いの 1 つは、遷移を document.startViewTransition() でラップする必要がないことです。代わりに、CSS の @view-transition アットルールを使用して、ビュー遷移に関与する両方のページをオプトインします。

@view-transition {
  navigation: auto;
}

よりカスタムな効果を得るには、新しい pageswap または pagereveal イベント リスナーを使用して JavaScript をフックインします。これにより、ビュー遷移オブジェクトにアクセスできます。

pageswap を使用すると、古いスナップショットが取得される直前に、送信ページの最終的な変更を行うことができます。また、pagereveal を使用すると、初期化後に新しいページのレンダリングが開始される前に、新しいページをカスタマイズできます。

window.addEventListener('pageswap', async (e) => {
    // ...
});

window.addEventListener('pagereveal', async (e) => {
    // ...
});
複数ページのアプリでビューの切り替えを表示する。デモリンクを参照してください。

今後、ビューの切り替えを次のように拡張する予定です。

  • スコープ付きトランジション: トランジションを DOM サブツリーに制限し、ページの残りの部分をインタラクティブな状態に保ち、複数のビュー トランジションを同時に実行できるようにします。
  • ジェスチャー駆動のビュー遷移: ドラッグやスワイプのジェスチャーを使用して、クロスドキュメントのビュー遷移をトリガーし、ウェブ上でよりネイティブに近いエクスペリエンスを実現します。
  • CSS でのナビゲーション マッチング: JavaScript で pageswap イベントと pagereveal イベントを使用する代わりに、CSS でドキュメント間のビュー遷移を直接カスタマイズします。複数ページのアプリケーションのビュー遷移について、プリレンダリングで最も効率的に設定する方法など、詳しくは、Bramus Van Damme による次の講演をご覧ください。

エンジン対応の UI コンポーネント: 複雑なインタラクションを簡素化

複雑なウェブ アプリケーションの構築は簡単ではありませんが、CSS と HTML はこのプロセスをより管理しやすくするために進化しています。新機能と機能強化により、UI コンポーネントの作成が簡素化され、優れたエクスペリエンスの構築に集中できるようになりました。これは、CSS Working Group、Open UI Community Group、WHATWG(Web Hypertext Application Technology Working Group)などの主要な標準化団体やコミュニティ グループが参加する共同作業を通じて行われます。

デベロッパーが抱える大きな問題の一つに、プルダウン メニュー(select 要素)のスタイル設定機能という、一見するとシンプルなリクエストがあります。一見すると単純な問題に見えますが、レイアウトとレンダリング、スクロールとインタラクション、ユーザー エージェントのスタイル設定と CSS プロパティ、HTML 自体の変更など、プラットフォームの多くの部分に影響する複雑な問題です。

オプションを含むオプションのデータリスト、トリガー ボタン、インジケーター矢印、選択されたオプションを含む選択。
select の各部分の内訳

プルダウンは多くの部分で構成され、次のような考慮すべき多くの状態を含んでいます。

  • キーボード バインディング(インタラクションの開始/終了)
  • クリックして閉じる
  • アクティブなポップオーバーの管理(1 つのポップオーバーが開くと他のポップオーバーを閉じる)
  • タブのフォーカス管理
  • 選択したオプション値を可視化する
  • 矢印のインタラクション スタイル
  • 状態管理(開閉)

現在、この状態をすべて自分で管理するのは難しいですが、プラットフォームもそれを容易にしていません。この問題を解決するため、これらの要素を分解し、ドロップダウンのスタイル設定を可能にするだけでなく、さらに多くのことを可能にするいくつかのプリミティブな機能をリリースしています。

Popover API

まず、popover というグローバル属性をリリースしました。この属性は数週間前に Baseline の新規利用可能ステータスに達しました。

Browser Support

  • Chrome: 114.
  • Edge: 114.
  • Firefox: 125.
  • Safari: 17.

Source

ポップオーバー要素は、ボタンなどの呼び出し元または JavaScript で開かれるまで display: none で非表示になります。基本的なポップオーバーを作成するには、要素にポップオーバー属性を設定し、popovertarget を使用してその ID をボタンにリンクします。ボタンが呼び出し元になり、

デモのビジュアル

ライブデモ

<button popovertarget="my-popover">Open Popover</button>

<div id="my-popover" popover>
  <p>I am a popover with more information.</p>
</div>

popover 属性が有効になったため、ブラウザは次のような多くのキー動作をスクリプトを追加することなく処理します。

  • 最上位レイヤへの昇格。: ページの他の部分とは別のレイヤなので、z-index を操作する必要はありません。
  • ライト ディスミス機能。: ポップオーバー領域の外側をクリックすると、ポップオーバーが閉じ、フォーカスが戻ります。
  • デフォルトのタブ フォーカス管理。: ポップオーバーを開くと、次のタブがポップオーバー内で停止します。
  • 組み込みキーボード バインディング。: esc キーを押すか、ダブル切り替えを行うと、ポップオーバーが閉じ、フォーカスが戻ります。
  • デフォルトのコンポーネント バインディング。: ブラウザがポップオーバーをトリガーに意味的に接続します。
GitHub のホーム画面 GitHub のホームページのメニュー。

このポップオーバー API を、意識せずにすでに使用しているかもしれません。GitHub は、ホームページの [New] メニューと pull リクエストのレビューの概要にポップオーバーを実装しました。この機能は、古いブラウザをサポートするために、Oddbird が GitHub の Keith Cirkel の多大なサポートを受けて構築した ポップオーバー ポリフィルを使用して、段階的に強化されました。

「ポップオーバーに移行することで、文字どおり数千行のコードを非推奨にすることができました。Popover は、魔法の z-index 番号を扱う必要性をなくし、宣言型のボタン動作で正しいアクセシビリティ ツリーの関係を確立し、フォーカス動作を組み込むことで、デザイン システムがパターンを正しく実装することを大幅に容易にします。- Keith Cirkel 氏、ソフトウェア エンジニア、GitHub」

開始エフェクトと終了エフェクトのアニメーション

ポップオーバーがある場合は、インタラクションを追加することをおすすめします。昨年、ポップオーバーのアニメーションをサポートするために、4 つの新しいインタラクション機能が追加されました。これには次のものが含まれます。

キーフレーム タイムラインで displaycontent-visibility をアニメーション化する機能。

display などの離散プロパティのトランジションを有効にする allow-discrete キーワードを含む transition-behavior プロパティ。

Browser Support

  • Chrome: 117.
  • Edge: 117.
  • Firefox: 129.
  • Safari: 17.4.

Source

display: none からトップレイヤへのエントリ効果をアニメーション化する @starting-style ルール。

Browser Support

  • Chrome: 117.
  • Edge: 117.
  • Firefox: 129.
  • Safari: 17.5.

Source

アニメーション中のトップレイヤの動作を制御するオーバーレイ プロパティ。

Browser Support

  • Chrome: 117.
  • Edge: 117.
  • Firefox: not supported.
  • Safari: not supported.

Source

これらのプロパティは、ポップオーバーかダイアログかを問わず、トップレイヤにアニメーションで表示するすべての要素で機能します。バックドロップ付きのダイアログの場合、全体は次のようになります。

デモのビジュアル

ライブデモ

dialog, ::backdrop{
  opacity: 0;
  transition: opacity 1s, display 1s allow-discrete, overlay 1s allow-discrete;
}

[open], [open]::backdrop {
  opacity: 1;
}

@starting-style {
  [open], [open]::backdrop {
    opacity: 0;
  }
}

まず、@starting-style を設定して、ブラウザがこの要素を DOM にアニメーション化するスタイルを認識できるようにします。これは、ダイアログとバックドロップの両方に対して行われます。次に、ダイアログとバックドロップの両方の開いた状態のスタイルを設定します。ダイアログの場合は open 属性を使用し、ポップオーバーの場合は ::popover-open 疑似要素を使用します。最後に、allow-discrete キーワードを使用して opacitydisplayoverlay をアニメーション化し、離散プロパティを遷移できるアニメーション モードを有効にします。

アンカーの配置

ポップオーバーは、物語の始まりにすぎませんでした。非常にエキサイティングなアップデートとして、Chrome 125 以降でアンカー ポジショニングのサポートが利用可能になりました。

Browser Support

  • Chrome: 125.
  • Edge: 125.
  • Firefox: not supported.
  • Safari: 26.

Source

アンカー ポジショニングを使用すると、数行のコードだけで、ブラウザが位置指定された要素を 1 つ以上のアンカー要素に固定するロジックを処理できます。次の例では、各ボタンにシンプルなツールチップがアンカーされ、下部中央に配置されています。

デモのビジュアル

ライブデモ

CSS でアンカー位置関係を設定するには、アンカー要素(この場合はボタン)の anchor-name プロパティと、位置指定要素(この場合はツールチップ)の position-anchor プロパティを使用します。次に、anchor() 関数を使用して、アンカーに対する絶対位置または固定位置を適用します。次のコードでは、ツールチップの上部をボタンの下部に配置します。

.anchor {
  anchor-name: --my-anchor;
}

.positioned {
  position: absolute;
  position-anchor: --my-anchor;
}

または、アンカー関数でアンカー名を直接使用し、position-anchor プロパティをスキップします。これは、複数の要素にアンカーを設定する場合に便利です。

.anchor {
  anchor-name: --my-anchor;
}

.positioned {
  position: absolute;
  top: anchor(--my-anchor bottom);
}

最後に、justify プロパティと align プロパティに新しい anchor-center キーワードを使用して、位置指定された要素をアンカーの中央に配置します。

.anchor {
  anchor-name: --my-anchor;
}

.positioned {
  position: absolute;
  top: anchor(--my-anchor bottom);
  justify-self: anchor-center;
}

アンカー位置指定をポップオーバーで使用すると非常に便利ですが、アンカー位置指定を使用するうえでポップオーバーは必須ではありません。アンカー ポジショニングは、2 つ以上の要素で使用して、視覚的な関係を作成できます。実際、Roman Komarov の記事に触発された次のデモでは、リストアイテムにカーソルを合わせたり、タブで移動したりすると、下線スタイルがリストアイテムに固定される様子が示されています。

デモのビジュアル

ライブデモ

この例では、アンカー関数を使用して、leftrightbottom の物理プロパティを使用してアンカー位置を設定します。リンクのいずれかにカーソルを合わせると、ターゲット アンカーが変更され、ブラウザがターゲットを移動して位置を適用し、同時に色をアニメーション化して、すっきりとした効果を生み出します。

ul::before {
  content: "";
  position: absolute;
  left:   anchor(var(--target) left);
  right:  anchor(var(--target) right);
  bottom: anchor(var(--target) bottom);
  ...
}

li:nth-child(1) { --anchor: --item-1 }
ul:has(:nth-child(1) a:is(:hover, :focus-visible)) {
  --target: --item-1;
  --color: red;
}

inset-area のポジショニング

以前に使用したことのあるデフォルトの方向絶対位置指定に加えて、アンカー位置指定 API の一部としてインセット領域と呼ばれる新しいレイアウト メカニズムが追加されました。インセット領域を使用すると、それぞれのアンカーに対して位置指定された要素を簡単に配置できます。これは、アンカー要素が中央にある 9 セルグリッドで機能します。たとえば、inset-area: top は配置された要素を上部に配置し、inset-area: bottom は配置された要素を下部に配置します。

最初のアンカー デモの簡略版は、inset-area を使用すると次のようになります。

.anchor {
  anchor-name: --my-anchor;
}

.positioned {
  position: absolute;
  position-anchor: --my-anchor;
  inset-area: bottom;
}

これらの位置の値とスパン キーワードを組み合わせて、中央の位置から左にスパン、右にスパン、またはすべてにスパンして、使用可能な列または行のセット全体を占有することができます。論理プロパティも使用できます。このレイアウト メカニズムを視覚化して把握しやすくするには、Chrome 125 以降のこちらのツールをご覧ください。

これらの要素はアンカーされているため、アンカーが移動すると、配置された要素がページ内で動的に移動します。この場合、コンテナクエリでスタイル設定されたカード要素があり、その要素は固有のサイズに基づいてサイズ変更されます(メディアクエリでは実現できません)。また、カード UI の変更に合わせて、アンカー付きメニューが新しいレイアウトに移動します。

デモのビジュアル

ライブデモ

position-try-options を使用した動的アンカー位置

ポップオーバーとアンカーの配置を組み合わせることで、メニューとサブメニューのナビゲーションを簡単に作成できます。また、アンカー要素がビューポートの端に達したときに、ブラウザに位置の変更を処理させることもできます。これを行うにはいくつかの方法があります。1 つ目は、独自のポジショニング ルールを作成することです。この場合、サブメニューは最初に [ストアフロント] ボタンの右側に配置されます。ただし、メニューの右側に十分なスペースがない場合に @position-try ブロックを作成し、カスタム識別子 --bottom を指定できます。次に、position-try-options を使用してこの @position-try ブロックをアンカーに接続します。

これで、ブラウザはこれらのアンカー状態を切り替え、まず右側の位置を試し、次に下部に移動します。この操作は、スムーズなトランジションで行うことができます。

デモのビジュアル

ライブデモ

#submenu {
  position-anchor: --submenu;
  top: anchor(top);
  left: anchor(right);
  margin-left: var(--padding);

  position-try-options: --bottom;

  transition: top 0.25s, left 0.25s;
  width: max-content;
}

@position-try --bottom {
  top: anchor(left);
  left: anchor(bottom);
  margin-left: var(--padding);
}

明示的な配置ロジックに加えて、ブロックまたはインラインの方向でアンカーを反転させるなどの基本的なインタラクションが必要な場合は、ブラウザが提供するキーワードがいくつかあります。

position-try-options: flip-block, flip-inline;

シンプルなフリップ エクスペリエンスの場合は、これらのフリップ キーワード値を利用して、position-try 定義の記述を完全にスキップします。これで、数行の CSS だけで、位置に応じたアンカー付き要素を完全に機能させることができます。

デモのビジュアル

ライブデモ

.tooltip {
  inset-area: top;
  position-try-options: flip-block;
}

詳しくは、アンカーの配置をご覧ください。

レイヤード UI の今後

テザリングされたエクスペリエンスはどこにでもあり、この投稿で紹介した機能セットは、創造性を発揮し、アンカー配置された要素とレイヤード インターフェースをより適切に制御するための優れたスタートとなります。しかし、これはほんの始まりにすぎません。たとえば、現在 popover は、呼び出し要素としてボタンを使用する場合、または JavaScript を使用する場合にのみ機能します。Wikipedia スタイルのプレビューなど、ウェブ プラットフォーム全体で見られるパターンでは、リンクから、また、ユーザーが興味を示したときに(必ずしもクリックしなくても、ホバーやタブ フォーカスなど)ポップオーバーをトリガーできるようにする必要があります。

ポップオーバー API の次のステップとして、これらのニーズを解決し、適切なアクセシビリティ フックを組み込んでこれらのエクスペリエンスを簡単に再現できるようにする interesttarget に取り組んでいます。これは解決が難しいアクセシビリティの問題であり、理想的な動作については多くの未解決の問題がありますが、プラットフォーム レベルでこの機能を解決して標準化することで、すべてのユーザーのエクスペリエンスが向上するはずです。

<a interesttarget="my-tooltip">Hover/Focus to show the tooltip</a>

<span popover=hint id="my-toolip">This is the tooltip</span>

また、Keith Cirkel 氏と Luke Warlow 氏という 2 人のサードパーティ デベロッパーの協力により、将来を見据えた別の汎用インボーカー(invoketarget)も Canary でテストできるようになりました。invoketarget は、popovertarget が提供する宣言型のデベロッパー エクスペリエンスをサポートしています。このエクスペリエンスでは、<dialog><details><video><input type="file"> などのすべてのインタラクティブ要素に対して正規化されたポップオーバーが提供されます。

<button invoketarget="my-dialog">
  Open Dialog
</button>

<dialog id="my-dialog">
  Hello world!
</dialog>

この API ではまだ対応していないユースケースがあることは承知しています。たとえば、アンカー要素をアンカーに接続する矢印のスタイル設定(特にアンカー要素の位置が変化する場合)や、要素がバウンディング ボックスに達したときに別の設定位置にスナップするのではなく、ビューポート内で「スライド」して留まるようにする機能などです。この強力な API のリリースを楽しみにしておりますが、今後さらに機能を拡張していく予定です。

スタイリング可能な選択

popoveranchor を組み合わせて使用することで、カスタマイズ可能な選択プルダウンを最終的に有効にする作業が進められています。幸いなことに、多くの進展がありました。残念ながら、この API は現時点ではまだ試験運用版です。ライブデモや進捗状況の最新情報をご紹介し、皆様からのフィードバックをいただければ幸いです。まず、ユーザーが新しいカスタマイズ可能な選択エクスペリエンスを有効にする方法について進展がありました。現在、この処理を行う方法として、CSS で appearance プロパティを appearance: base-select に設定する方法が開発中です。外観を設定すると、新しいカスタマイズ可能な選択機能が有効になります。

select {
  appearance: base-select;
}

appearance: base-select に加えて、いくつかの新しい HTML の更新があります。たとえば、オプションを datalist でラップしてカスタマイズしたり、オプションに画像などの任意の非インタラクティブ コンテンツを追加したりできます。また、新しい要素 <selectedoption> にもアクセスできるようになります。この要素は、オプションの内容を反映し、必要に応じてカスタマイズできます。この要素はとても便利です。

デモのビジュアル

フラグのデモ

ライブデモ

<select>
  <button type=popover>
    <selectedoption></selectedoption>
  </button>
  <datalist>
    <option value="" hidden>
      <p>Select a country</p>
    </option>
    <option value="andorra">
      <img src="Flag_of_Andorra.svg" />
      <p>Andorra</p>
    </option>
    <option value="bolivia">
      <img src="Flag_of_Bolivia.svg" />
      <p>Bolivia</p>
    </option>
...
  </datalist>
</select>

次のコードは、Gmail UI で <selectedoption> をカスタマイズする方法を示しています。ここでは、スペースを節約するために、選択した返信のタイプを視覚的なアイコンで表しています。selectedoption 内で基本的な表示スタイルを使用すると、オプションのスタイルとプレビューのスタイルを区別できます。この場合、オプションに表示されるテキストは selectedoption で視覚的に非表示にできます。

デモのビジュアル

Gmail のデモ

ライブデモ

selectedoption .text {
  display: none;
}

この API で <select> 要素を再利用する最大のメリットの 1 つは、下位互換性です。この国選択では、コンテンツをユーザーが簡単に解析できるように、オプションに国旗の画像が表示されたカスタマイズされた UI が表示されています。サポートされていないブラウザは、カスタムボタン、datalist、selectedoption、オプション内の画像など、理解できない行を無視するため、フォールバックは現在のデフォルトの選択 UI と同様になります。

サポートされていないブラウザでは、現在の選択機能が利用できます。
左側はサポートされているブラウザのビジュアル、右側はサポートされていないブラウザのフォールバック。

カスタマイズ可能なセレクトを使用すると、可能性は無限に広がります。Airbnb スタイルの国選択ツールは、レスポンシブ デザインの巧妙なスタイルが採用されているため、特に気に入っています。この機能は、今後リリースされるスタイリング可能な select で実現できます。これは、ウェブ プラットフォームに不可欠な機能です。

デモのビジュアル

ライブデモ

限定アコーディオン

Chrome チームが取り組んでいる UI コンポーネントは、特定のスタイルの解決(およびそれに伴うすべての要素)だけではありません。最初の追加コンポーネントの更新は、アコーディオン内の項目を一度に 1 つしか開くことができない排他的アコーディオンを作成する機能です。

Browser Support

  • Chrome: 120.
  • Edge: 120.
  • Firefox: 130.
  • Safari: 17.2.

これを有効にするには、複数の詳細要素に同じ名前の値を適用して、ラジオボタンのグループのように、接続された詳細のグループを作成します。

アコーディオンの限定デモ
<details name="learn-css" open>
  <summary>Welcome to Learn CSS!</summary>
</details>

<details name="learn-css">
  <summary>Box Model</summary>
  <p>...</p>
</details>

<details name="learn-css">
  <summary>Selectors</summary>
  <p>...</p>
</details>

:user-valid:user-invalid

UI コンポーネントの改善点としては、:user-valid:user-invalid の疑似クラスもあります。最近すべてのブラウザで安定した :user-valid 疑似クラスと :user-invalid 疑似クラスは、:valid 疑似クラスと :invalid 疑似クラスと同様に動作しますが、ユーザーが入力に大幅に操作した後にのみフォーム コントロールを照合します。つまり、フォーム値が操作されたか、変更されたかを判断するために必要なコードが大幅に減ります。これは、ユーザー フィードバックの提供に非常に役立ち、以前は必要だったスクリプトの多くを削減できます。

Browser Support

  • Chrome: 119.
  • Edge: 119.
  • Firefox: 88.
  • Safari: 16.5.

Source

デモのスクリーンキャスト

ライブデモ

input:user-valid,
select:user-valid,
textarea:user-valid {
    --state-color: green;
    --bg: linear-gradient(...);
}

input:user-invalid,
select:user-invalid,
textarea:user-invalid {
    --state-color: red;
    --bg: linear-gradient(...);
}

詳しくは、user-* フォーム検証疑似要素をご覧ください。

field-sizing: content

最近追加された便利なコンポーネント アップデートとして、field-sizing: content があります。これは、入力やテキストエリアなどのフォーム コントロールに適用できます。これにより、入力のサイズをコンテンツに応じて拡大(または縮小)できます。field-sizing: content は、テキストエリアで特に便利です。入力ボックスが小さすぎて、プロンプトの冒頭部分に書いた内容を確認するためにスクロールする必要があるような固定サイズに制限されなくなります。

Browser Support

  • Chrome: 123.
  • Edge: 123.
  • Firefox: not supported.
  • Safari Technology Preview: supported.

Source

デモのスクリーンキャスト

ライブデモ

textarea, select, input {
  field-sizing: content;
}

詳しくは、フィールドのサイズ設定をご覧ください。

<hr><select>

選択で <hr>(水平ルール要素)を有効にできることも、小さくても便利なコンポーネント機能です。この要素に意味的な用途はあまりありませんが、選択リスト内のコンテンツを適切に分離するのに役立ちます。特に、プレースホルダ値など、optgroup でグループ化する必要がないコンテンツを分離するのに役立ちます。

スクリーンショットを選択

Chrome のライトモードとダークモードで選択された hr のスクリーンショット

[ライブデモ] を選択します。

<select name="majors" id="major-select">
  <option value="">Select a major</option>
  <hr>
  <optgroup label="School of Fine Arts">
    <option value="arthist">
Art History
  </option>
  <option value="finearts">
    Fine Arts
  </option>
...
</select>

詳しくは、select で hr を使用するをご覧ください。

生活の質の向上

Google は常にイテレーションを繰り返しており、これはインタラクションやコンポーネントに限った話ではありません。この 1 年間には、他にも多くの QOL アップデートが実施されています。

先読みを使用したネスト

ネイティブ CSS ネストは昨年すべてのブラウザに導入され、先読みをサポートするように改善されました。つまり、要素名の前の & は不要になりました。これにより、ネストがはるかに人間工学的になり、これまで使用してきたものと似たような感覚になります。

Browser Support

  • Chrome: 120.
  • Edge: 120.
  • Firefox: 117.
  • Safari: 17.2.

Source

CSS ネストの好きなところは、コンポーネントを視覚的にブロックし、そのコンポーネント内にコンテナ クエリやメディア クエリなどの状態や修飾子を含めることができることです。以前は、具体性を高めるために、これらのクエリをすべてファイルの末尾にグループ化していました。これで、コードの残りの部分のすぐ横に、意味のある方法で記述できるようになりました。

.card {
  /* card base styles */

  h2 {
    /* child element style */
  }

  &.highlight {
    /* modifier style */
  }

  &:hover, &:focus {
    /* state styles */
  }

  @container (width >= 300px) {
    /* container query styles */
  }
}

ブロック レイアウトの align-content

もう 1 つの大きな変更点は、ブロック レイアウトで align-content などのセンタリング メカニズムを使用できるようになったことです。つまり、flex レイアウトや grid レイアウトを適用しなくても、また、それらのレイアウト アルゴリズムで望ましくないマージン統合の防止などの副作用を伴わずに、div 内で垂直方向の中央揃えなどの操作ができるようになりました。

Browser Support

  • Chrome: 123.
  • Edge: 123.
  • Firefox: 125.
  • Safari: 17.4.

スクリーンショット

ライブデモ

div {
  align-content: center;
}

Text-wrap: balance と pretty

レイアウトについて言えば、text-wrap: balancepretty の追加により、テキスト レイアウトが大幅に改善されました。text-wrap: balance はテキストのブロックをより均一にするために使用され、text-wrap: pretty はテキストの最終行のシングルトンを減らすことに重点を置いています。

デモのスクリーンキャスト

ライブデモ

次のデモでは、スライダーをドラッグして、見出しと段落に対する balancepretty の効果を比較できます。デモを別の言語に翻訳してみてください。
h1 {
  text-wrap: balance;
}

詳しくは、text-wrap: balance をご覧ください。

国際的なタイポグラフィの更新

CJK テキスト機能のタイポグラフィ レイアウトのアップデートでは、この 1 年間で多くの優れたアップデートが行われました。たとえば、自然なフレーズの境界で改行する word-break: auto-phrase 機能などです。

Browser Support

  • Chrome: 119.
  • Edge: 119.
  • Firefox: not supported.
  • Safari: not supported.

word-break: auto-phrase は、自然なフレーズの境界で改行します。
word-break: normalword-break: auto-phrase の比較

また、text-spacing-trim は、句読点文字間のカーニングを適用して、中国語、日本語、韓国語のタイポグラフィの可読性を高め、視覚的に美しい結果を実現します。

Browser Support

  • Chrome: 123.
  • Edge: 123.
  • Firefox: not supported.
  • Safari: not supported.

Source

CJK の句点の右半分が text-spacing-trim で削除されます。
句読点が連続して現れた場合は、CJK ピリオドの右半分を削除します。

相対色の構文

カラー テーマ設定の世界では、相対色構文という大きなアップデートがありました。

この例では、Oklch ベースのテーマ設定を使用しています。スライダーに基づいて色相値が調整されると、テーマ全体が変化します。これは相対色構文で実現できます。背景は色相に基づいてメインの色を使用し、明度、彩度、色相の各チャンネルを調整して値を調整します。--i は値のグラデーションのリスト内の兄弟インデックスです。ステッピングとカスタム プロパティ、相対色構文を組み合わせてテーマを構築する方法を示しています。

デモのスクリーンキャスト

ライブデモ

次のデモでは、スライダーをドラッグして、見出しと段落に対する balancepretty の効果を比較できます。デモを別の言語に翻訳してみてください。
:root {
  --hue: 230;
  --primary: oklch(70% .2 var(--hue));
}

li {
  --_bg: oklch(from var(--primary)
    calc(l - (var(--i) * .05))
    calc(c - (var(--i) * .01))
    calc(h - (var(--i) + 5)));
}

light-dark() 関数

light-dark() 関数とともに、テーマ設定はより動的でシンプルなものになりました。

Browser Support

  • Chrome: 123.
  • Edge: 123.
  • Firefox: 120.
  • Safari: 17.5.

Source

light-dark() 関数は、カラーテーマ オプションを簡素化して、テーマ スタイルをより簡潔に記述できるようにするエルゴノミクス改善です。この視覚的な図で Adam Argyle が見事に示しています。以前は、テーマ オプションを設定するために、2 つの異なるコードブロック(デフォルトのテーマとユーザー設定のクエリ)が必要でした。これで、light-dark() 関数を使用して、ライトテーマとダークテーマの両方のスタイル オプションを同じ CSS 行に記述できます。

light-dark() の可視化。詳しくは、デモをご覧ください。
html {
  color-scheme: light dark;
}

button {
    background-color: light-dark(lightblue, darkblue);
}

ユーザーがライトテーマを選択した場合、ボタンの背景は明るい青色になります。ユーザーがダークテーマを選択している場合、ボタンの背景はダークブルーになります。

:has()セレクタ

また、最新の UI について語るうえで、昨年最も大きな影響を与えた相互運用性のハイライトの 1 つである :has() セレクタについて触れないわけにはいきません。このセレクタは、昨年の 12 月にブラウザ間で実装されました。この API は、論理スタイルを記述するうえで画期的なものです。

Browser Support

  • Chrome: 105.
  • Edge: 105.
  • Firefox: 121.
  • Safari: 15.4.

Source

:has() セレクタを使用すると、子要素に特定の子があるかどうか、またはそれらの子が特定の状態にあるかどうかを確認できます。基本的には、親セレクタとしても機能します。

has() を使用して Tokopedia の比較ブロックのスタイルを設定するデモ。

:has() は、PolicyBazaar など、多くの企業にとって特に有用であることがすでに示されています。PolicyBazaar では、:has() を使用して、ブロックの内部コンテンツに基づいてブロックのスタイルを設定しています。たとえば、比較セクションでは、ブロック内に比較するプランがあるかどうか、またはブロックが空かどうかによってスタイルが調整されます。

「:has() セレクタを使用することで、ユーザーの選択の JavaScript ベースの検証を排除し、CSS ソリューションに置き換えることができました。このソリューションは、以前と同じエクスペリエンスでシームレスに動作しています。- Aman Soni 氏、PolicyBazaar テックリード」

コンテナクエリ

ウェブに追加されたもう一つの重要な機能がコンテナクエリです。これは、要素の親の固有サイズをクエリしてスタイルを適用する機能で、メディアクエリよりもはるかに細かい制御が可能です。メディアクエリはビューポート サイズのみをクエリします。コンテナクエリは、現在利用可能になり、使用頻度が増加しています。

Browser Support

  • Chrome: 105.
  • Edge: 105.
  • Firefox: 110.
  • Safari: 16.

Source

Angular は最近、angular.dev で美しい新しいドキュメント サイトをリリースしました。このサイトでは、コンテナ クエリを使用して、ページ上の利用可能なスペースに基づいてヘッダー ブロックのスタイルを設定しています。そのため、レイアウトが変更されて、複数列のサイドバー レイアウトから 1 列のレイアウトに変わっても、ヘッダー ブロックは自動的に調整されます。

Angular.dev サイトのヘッダーカードでコンテナクエリを紹介しています。

コンテナクエリがないと、このような処理は非常に難しく、パフォーマンスにも悪影響を及ぼします。リサイズ オブザーバーと要素オブザーバーが必要になるためです。これで、親のサイズに基づいて要素のスタイルを設定することが簡単になりました。

デモのスクリーンキャスト

ライブデモ

Angular ヘッダーカード コンテナクエリを再作成します。

@property

最後に、@property が Baseline に登場するのも間近です。これは、CSS カスタム プロパティ(CSS 変数とも呼ばれます)にセマンティックな意味を与えるための重要な機能であり、多くの新しいインタラクション機能を可能にします。@property では、CSS でのコンテキストの意味、型チェック、デフォルト値、フォールバック値も有効になります。範囲スタイルのクエリなど、さらに堅牢な機能を利用できるようになります。これはこれまで不可能だった機能であり、CSS の言語に深みをもたらします。

Browser Support

  • Chrome: 85.
  • Edge: 85.
  • Firefox: 128.
  • Safari: 16.4.

Source

デモのスクリーンキャスト

ライブデモ

@property --card-bg {
  syntax: "<color>";
  inherits: false;
  initial-value: #c0bae8;
}

まとめ

これらの強力な新しい UI 機能がブラウザ全体に実装されることで、可能性は無限に広がります。スクロール駆動型アニメーションとビュー トランジションによる新しいインタラクティブ エクスペリエンスにより、ウェブはこれまでになく流動的でインタラクティブになります。また、次世代の UI コンポーネントにより、ネイティブ エクスペリエンスを完全に削除することなく、堅牢で美しくカスタマイズされたコンポーネントをこれまで以上に簡単に構築できます。最後に、アーキテクチャ、レイアウト、タイポグラフィ、レスポンシブ デザインの品質改善は、小さな大きな問題を解決するだけでなく、さまざまなデバイス、フォーム ファクタ、ユーザーのニーズに対応する複雑なインターフェースを構築するために必要なツールをデベロッパーに提供します。

これらの新機能により、スクロール テリングやアンカー ポジショニングによる要素の相互固定などのパフォーマンスを重視する機能でサードパーティ スクリプトを削除したり、流動的なページ遷移を構築したり、ドロップダウンのスタイル設定を行ったり、コードの全体的な構造をネイティブに改善したりできるようになります。

ウェブ デベロッパーにとって、今は絶好のチャンスです。CSS3 の発表以来、これほどまでにエネルギーと興奮が感じられたことはありません。これまで必要とされてきたものの、実現は夢のまた夢だった機能が、ついに現実となり、プラットフォームの一部として組み込まれるようになりました。皆様のご意見のおかげで、これらの機能の優先順位を決定し、最終的に実現することができました。Google は、面倒で手間のかかる作業をネイティブで簡単に行えるように取り組んでいます。これにより、ブランドを差別化するコア機能やデザインの詳細など、重要な要素の構築に時間を費やせるようになります。

これらの新機能について詳しくは、developer.chrome.com と web.dev をご覧ください。チームがウェブ テクノロジーの最新情報を共有しています。スクロール駆動型アニメーション、ビュー遷移、アンカー ポジショニング、スタイル設定可能な選択などを試して、ご意見をお聞かせください。Google はお客様の声に真摯に向き合い、適切なサポートをお届けしてまいります。