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

ウェブ プラットフォームは常に革新を続けています。その最前線にあるのが、CSS とウェブ UI の機能です。ウェブ UI はまさに黄金期を迎えています。これまでにないスピードで新しい CSS 機能がブラウザに導入され、美しく魅力的なウェブ エクスペリエンスを作成するための可能性が広がっています。このブログ投稿では、CSS の現状を詳しく掘り下げ、ウェブ アプリケーションの構築方法を再定義する、ゲームチェンジャーとなる新機能の一部をご紹介します。これらの新機能は、Google I/O 2024 でライブ配信されました。

新しいインタラクティブな体験

ウェブ エクスペリエンスは基本的に、ユーザーとのやり取りです。そのため、質の高いユーザー インタラクションに投資することが非常に重要です。Google は、ウェブページ内の移動やウェブページ間の移動に関して、ウェブ上でこれまでにない機能を実現する大幅な改善に取り組んできました。

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

対応ブラウザ

  • Chrome: 115.
  • Edge: 115。
  • Firefox: フラグの背後。
  • Safari: サポートされていません。

ソース

名前が示すように、スクロールドリブン アニメーション 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 が解説します。機能の仕組み、用語、さまざまなエフェクトの作成方法、エフェクトを組み合わせて豊かなエクスペリエンスを構築する方法などについて学びます。ぜひご覧ください。

遷移を表示する

ウェブページでアニメーションを作成できる強力な新機能について説明しましたが、ページビューでアニメーションを作成してシームレスなユーザー エクスペリエンスを実現できるビュー遷移という強力な新機能もあります。ビュー遷移は、ウェブに新たなレベルの流動性をもたらします。1 つのページ内の異なるビュー間や、異なるページ間でシームレスな遷移を作成できます。

対応ブラウザ

  • Chrome: 111.
  • Edge: 111.
  • Firefox: サポートされていません。
  • Safari: 18。

ソース

Airbnb は、スムーズでシームレスなウェブ ナビゲーション エクスペリエンスを実現するために、ビュー遷移を UI に統合するテストをすでに行っています。ユーザーがサイト内を移動しながら、スムーズに行えるようにしました。

Airbnb で見られるような、同じドキュメント内のビューの遷移。
Maxwell Barvian のポートフォリオ。ビュー間のビュー遷移を紹介します。

これらのフルページ エフェクトは美しくシームレスですが、ユーザー操作でリストビューが更新されるようなマイクロ インタラクションも作成できます。この効果は、ビュー遷移で簡単に実現できます。

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

デモのビジュアル

ライブデモ

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;
}

遷移クラスを表示する

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

対応ブラウザ

  • Chrome: 125.
  • エッジ: 125。
  • Firefox: サポートされていません。
  • Safari: 18.2。

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

ビュー遷移の大きな改善点として、ビュー遷移の種類のサポートがあります。ビュー遷移タイプは、ページビューとの間でアニメーション化するときに、視覚的なビュー遷移を別の種類にしたい場合に便利です。

対応ブラウザ

  • Chrome: 125.
  • エッジ: 125。
  • Firefox: サポートされていません。
  • Safari: 18。

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

ページネーションのデモの録画。タイプによって、使用するアニメーションが決まります。有効な遷移タイプにより、スタイルシート内でスタイルが分離されます。

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

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

マルチページ ビューの遷移

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

対応ブラウザ

  • Chrome: 126。
  • Edge: 126。
  • Firefox: サポートされていません。
  • Safari Technology Preview: サポートされています。

この新しいクロスドキュメント機能セットには、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 ワーキング グループ、Open UI コミュニティ グループ、WHATWG(Web Hypertext Application Technology Working Group)など、複数の主要な標準化団体とコミュニティ グループが協力して行っています。

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

オプション、トリガーボタン、インジケーター矢印、選択したオプションを含むオプションのデータリストで選択します。
選択内容の分解

プルダウンは多くの要素で構成されており、次のような多くの状態を考慮する必要があります。

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

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

Popover API

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

対応ブラウザ

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

ソース

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

デモのビジュアル

ライブデモ

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

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

ポップオーバー属性が有効になったことで、ブラウザは追加のスクリプトなしで次のような多くの重要な動作を処理できるようになりました。

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

気づかないうちに、このポップオーバー API を使用している可能性もあります。GitHub は、ホームページの [新規] メニューと pull リクエストのレビュー概要にポップオーバーを実装しました。古いブラウザをサポートするために、Oddbird が GitHub の Keith Cirkel の支援を受けて作成した ポップオーバー ポリフィルを使用して、この機能を段階的に強化しました。

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

開始時と終了時のエフェクトをアニメーション化する

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

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

transition-behavior プロパティと allow-discrete キーワードを使用して、display などの離散プロパティの遷移を有効にします。

対応ブラウザ

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

ソース

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

対応ブラウザ

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

ソース

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

対応ブラウザ

  • Chrome: 117
  • Edge: 117.
  • Firefox: サポートされていません。
  • Safari: サポートされていません。

ソース

これらのプロパティは、ポップオーバーやダイアログなど、最上位レイヤにアニメーション化する要素に適用できます。バックドロップのあるダイアログの全体は次のようになります。

デモのビジュアル

ライブデモ

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 からアンカーの配置がサポートされるようになりました。

対応ブラウザ

  • Chrome: 125.
  • エッジ: 125。
  • Firefox: サポートされていません。
  • Safari: サポートされていません。

ソース

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

デモのビジュアル

ライブデモ

アンカー要素(この場合はボタン)の anchor-name プロパティと、配置された要素(この場合はツールチップ)の position-anchor プロパティを使用して、CSS でアンカー配置の関係を設定します。次に、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;
}

これらの位置値を span キーワードと組み合わせて、中央の位置から左、右、またはすべてにまたがって、使用可能な列または行のセット全体を占有するように指定できます。論理プロパティを使用することもできます。このレイアウト メカニズムを簡単に可視化して確認するには、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>

さらに、2 人のサードパーティ デベロッパーである Keith Cirkel 氏と Luke Warlow 氏の協力により、カナリアでテストできる、将来を見据えた別の一般的な呼び出し元(invoketarget)も用意されています。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 が表示されます。サポートされていないブラウザでは、カスタム ボタン、データリスト、selectedoption、オプション内の画像など、認識できない行は無視されるため、代替手段は現在のデフォルトの選択 UI に似たものになります。

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

カスタマイズ可能なセレクタを使用すると、可能性は無限大です。Airbnb スタイルの国選択ツールは、レスポンシブ デザインに適した巧みなスタイルが採用されている点が特に気に入っています。今後リリースされるスタイル設定可能なセレクタでは、この他にも多くのことが可能になります。これは、ウェブ プラットフォームに必要不可欠な機能です。

デモのビジュアル

ライブデモ

限定アコーディオン

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

対応ブラウザ

  • Chrome: 120。
  • エッジ: 120。
  • Firefox: 130。
  • Safari: 17.2。

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

限定の折りたたみ式デモ
<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 疑似クラスと同様に動作しますが、ユーザーが入力を大幅に操作した後にのみフォーム コントロールと一致します。つまり、フォームの値が操作されたか「変更済み」になったかどうかを判断するために必要なコードが大幅に削減されます。これはユーザー フィードバックの提供に非常に役立ち、これまでこの処理に必要だった大量のスクリプトを削減できます。

対応ブラウザ

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

ソース

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

ライブデモ

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 があります。これは、入力や textarea などのフォーム コントロールに適用できます。これにより、入力のサイズはコンテンツに応じて拡大(または縮小)できます。field-sizing: content は textarea に特に便利です。固定サイズに解決されなくなるため、入力ボックスが小さすぎる場合に、プロンプトの前半で入力した内容を確認するためにスクロールする必要がなくなります。

対応ブラウザ

  • Chrome: 123。
  • Edge: 123。
  • Firefox: サポートされていません。
  • Safari: サポートされていません。

ソース

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

ライブデモ

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 のネスト機能は昨年すべてのブラウザでリリースされ、その後、先読みをサポートするように改善されました。つまり、要素名の前に & を付ける必要がなくなりました。これにより、ネストがより人間工学に基づいたものになり、以前に慣れていたものに近づきました。

対応ブラウザ

  • Chrome: 120。
  • エッジ: 120。
  • Firefox: 117.
  • Safari: 17.2。

ソース

CSS のネスト機能の利点の一つは、コンポーネントを視覚的にブロックし、そのコンポーネント内に状態や修飾子(コンテナクエリやメディアクエリなど)を含めることができることです。以前は、特定の目的のために、これらのクエリをすべてファイルの下部にグループ化していました。これで、他のコードのすぐ横に、適切な方法で記述できるようになりました。

.card {
  /* card base styles */

  h2 {
    /* child element style */
  }

  &.highlight {
    /* modifier style */
  }

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

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

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

ブロック レイアウトで align-content などの中央揃えメカニズムを使用できるようになったのも、非常に便利な変更です。つまり、flex レイアウトやグリッド レイアウトを適用しなくても、div 内で垂直方向に中央揃えを行うことができます。また、これらのレイアウト アルゴリズムでは望ましくない、余白の圧縮を防ぐなどの副作用も発生しません。

対応ブラウザ

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

スクリーンショット

ライブデモ

div {
  align-content: center;
}

テキストの折り返し: バランスと美しさ

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

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

ライブデモ

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

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

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

CJK テキスト機能のタイポグラフィ レイアウトの更新: 自然なフレーズ境界で行を折り返す word-break: auto-phrase 機能など、過去 1 年間で多くの優れた更新が行われました。

対応ブラウザ

  • Chrome: 119。
  • Edge: 119.
  • Firefox: サポートされていません。
  • Safari: サポートされていません。

word-break: 自然なフレーズ境界で行を折り返します。
word-break: normalword-break: auto-phrase の比較

text-spacing-trim: 句読点の間にケーニングを適用し、中国語、日本語、韓国語のタイポグラフィの可読性を高めて、視覚的に優れた結果を得ることができます。

対応ブラウザ

  • Chrome: 123。
  • Edge: 123。
  • Firefox: サポートされていません。
  • Safari: サポートされていません。

ソース

text-spacing-trim を使用すると、CJK ピリオドの右半分が削除されます。
句読点が 1 行に複数ある場合は、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() 関数とともに、テーマ設定はより動的かつ簡素になりました。

対応ブラウザ

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

ソース

light-dark() 関数は、Adam Argyle によるこのビジュアル ダイアグラムで示されているように、色のテーマ設定オプションを簡素化して、テーマスタイルをより簡潔に記述できるようにする、人間工学的な改善です。以前は、テーマ オプションを設定するには、2 つの異なるコードブロック(デフォルト テーマとユーザー設定クエリ)が必要でした。これで、light-dark() 関数を使用して、明るいテーマと暗いテーマの両方のスタイル オプションを CSS の同じ行に記述できるようになりました。

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

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

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

:has()セレクタ

モダン UI についてお話しする際に、昨年最もインパクトのあった相互運用性のハイライトの一つである :has() セレクタについて触れないわけにはいきません。このセレクタは昨年 12 月にすべてのブラウザにリリースされました。この API は、論理スタイルの記述に革命をもたらします。

対応ブラウザ

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

ソース

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

Tokopedia の比較ブロックのスタイル設定に has() が使用されているデモ。

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

「:has() セレクタにより、ユーザーの選択に対する JavaScript ベースの検証を排除し、以前と同じエクスペリエンスでシームレスに動作する CSS ソリューションに置き換えることができました。–Aman Soni、Tech Lead、PolicyBazaar」

コンテナクエリ

ウェブに新たに追加され、使用が拡大している重要な機能として、コンテナクエリがあります。これにより、要素の親の固有サイズをクエリしてスタイルを適用できるようになります。ビューポート サイズのみをクエリするメディアクエリよりも、はるかにきめ細かい調整が可能です。

対応ブラウザ

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

ソース

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

ヘッダーカードにコンテナ クエリを表示する
Angular.dev サイト。

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

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

ライブデモ

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

@property

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

対応ブラウザ

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

ソース

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

ライブデモ

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

まとめ

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

これらの新機能により、スクロール ナレーションやアンカー ポジショニングによる要素同士の結合など、パフォーマンスに影響する機能のサードパーティ スクリプトを削除し、スムーズなページ遷移を構築し、プルダウンをスタイル設定し、コードの全体的な構造をネイティブに改善できるようになります。

ウェブ デベロッパーにとって今は絶好のタイミングです。CSS3 の発表以来、それほど大きな盛り上がりはありませんでした。これまで必要としながらも、実現を夢見ていた機能が、ついに現実となり、プラットフォームの一部になりました。皆様のご意見のおかげで、これらの機能を優先して開発し、ついに実現することができました。Google は、面倒で時間のかかる作業をネイティブに簡単に行えるようにすることで、ブランドを差別化するコア機能やデザインの細部など、重要なことにより多くの時間を費やせるように取り組んでいます。

これらの新機能の詳細については、developer.chrome.com と web.dev で最新情報をご確認ください。これらのサイトでは、ウェブ技術に関する最新情報を Google チームが共有しています。スクロール ドリブン アニメーション、ビュー遷移、アンカーの配置、スタイル設定可能な選択などをお試しいただき、ご意見をお聞かせください。ご意見をお聞かせください。