ウェブ プラットフォームはイノベーションに満ちており、このエキサイティングな進化の最前線にいたのが CSS とウェブ UI の機能です。ウェブ UI は黄金期を迎えています。新しい CSS 機能がこれまでにないペースでブラウザ全体に導入され、美しく魅力的なウェブ エクスペリエンスを生み出す可能性が広がります。このブログ投稿では、CSS の現状を深く掘り下げ、Google I/O 2024 で発表された、ウェブ アプリケーションの構築方法を再定義する革新的な新機能をいくつか紹介します。
斬新なインタラクティブ エクスペリエンス
ウェブ エクスペリエンスとは、基本的には、ユーザーとユーザーとの間でやり取りすることです。そのため、質の高いユーザー インタラクションに投資することは非常に重要です。Google では現在、ウェブページ内での移動やウェブページ間の移動をウェブでこれまでになく行えるよう、大きな改善に取り組んできました。
スクロールドリブン アニメーション
名前が示すように、スクロールドリブン アニメーション 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 により、自分で作成したカスタム スクリプトでも、追加のサードパーティ依存関係のインクルードでも、維持する必要があるコードの負担が軽減されます。また、さまざまなスクロール オブザーバーを用意する必要がなくなるため、パフォーマンスが大幅に向上します。これは、新しい API を CSS で直接使用する場合でも、JavaScript フックを使用する場合でも、コンポジタでアニメーション化できるプロパティ(変形や不透明度など)をアニメーション化する場合に、スクロールドリブン アニメーションがメインスレッドの外部で動作するためです。
Tokopedia は最近、スクロールドリブン アニメーションを使用して、スクロール時にプロダクトのナビゲーション バーが表示されるようにしました。この API を使用すると、コード管理とパフォーマンスの両面で大きなメリットが得られます。
「従来の JS スクロール イベントを使用した場合と比較して、コード行を最大 80% 削減できました。スクロール中の平均 CPU 使用率が 50% から 2% に減少することを確認できました。- Tokopedia、シニア ソフトウェア エンジニア Andy Wihalim 氏
スクロール効果の未来
こうした効果によってウェブがより魅力的な場所になり続けることはわかっており、私たちはすでに次の展開について考えています。これには、新しいアニメーション タイムラインを使用するだけでなく、スクロール ポイントを使用してアニメーションの開始をトリガーする機能(スクロール トリガー アニメーション)も含まれます。
また、今後、スクロール機能がさらに追加される予定です。次のデモは、これらの将来的な機能の組み合わせを示しています。CSS scroll-start-target
を使用して選択ツール内の初期日時を設定し、JavaScript scrollsnapchange
イベントを使用してヘッダー日付を更新することで、データをスナップされたイベントと簡単に同期できるようにしています。
これを利用して、JavaScript の scrollsnapchanging
イベントで選択ツールをリアルタイムで更新することもできます。
現在、これらの特定の機能は、フラグ付きの Canary 版のみですが、これまでプラットフォームで構築が不可能または非常に難しかった機能を解放し、スクロールベースのインタラクションの可能性を浮き彫りにしています。
スクロールドリブン アニメーションの利用を開始する方法について詳しくは、Chrome for Developers YouTube チャンネルで新しい動画シリーズを公開しています。ぜひご覧ください。ここでは、Bramus Van Damme のスクロールドリブン アニメーションの基本を学びます。この機能の仕組み、語彙、エフェクトを作成するさまざまな方法、エフェクトを組み合わせてリッチなエクスペリエンスを構築する方法などを学びます。おすすめの動画シリーズです
ビュー遷移
ここまで、ウェブページ内でアニメーション化する優れた新機能について説明しましたが、ページビュー間のアニメーションでシームレスなユーザー エクスペリエンスを実現するビュー遷移という強力な新機能も追加しました。ビュー遷移により、ウェブに新たなレベルの流動性がもたらされ、単一ページ内の異なるビュー間、または異なるページ間でのシームレスな移行を実現できます。
Airbnb は、スムーズでシームレスなウェブ ナビゲーション エクスペリエンスを実現するために、ビュー遷移を UI に統合するテストをすでに行っている企業の 1 つです。たとえば、リスティング エディタのサイドバーから、写真の編集や設備の追加まで、すべて滑らかなユーザーフローの中で行えます。
これらのページ全体への効果は美しくシームレスですが、ミクロ インタラクションを作成することもできます。この例では、ユーザーの操作に応じてリストビューが更新される例です。この効果は、ビュー遷移によって簡単に実現できます。
シングルページ アプリケーションでビュー遷移をすばやく有効にする方法は、document.startViewTransition
を使用してインタラクションをラップし、DOM ノードを作成する際に JavaScript を使用して遷移中の各要素が view-transition-name
を持つか、インラインで、または動的に遷移するかを確認するのと同じくらい簡単です。
デモのビジュアル
ライブデモ
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;
}
遷移クラスを表示する
ビュー遷移名を使用して、ビュー遷移にカスタム アニメーションを適用できますが、多くの要素が遷移すると煩雑になることがあります。今年のビュー遷移に関する最初の新しいアップデートでは、この問題が簡素化され、カスタム アニメーションに適用できるビュー遷移クラスを作成する機能が導入されました。
対応ブラウザ
- 125
- 125
- x
- x
表示の切り替えタイプ
ビュー遷移に関するもう一つの大きな改善点は、ビュー遷移タイプのサポートです。ビュー遷移タイプは、ページビュー間でアニメーション化する際に、別の種類の視覚的なビュー遷移が必要な場合に役立ちます。
たとえば、ホームページからブログページに戻るアニメーションとは、ブログページがホームページに戻るアニメーションとは異なる方法の場合です。または、この例のように、左から右へ、またはその逆に、異なる方法でページを入れ替えたい場合もあります。以前は、スタイルを適用するために DOM にクラスを追加して、後でそのクラスを削除する必要がありましたが、ビュー遷移タイプを使用すると、古い遷移をブラウザでクリーンアップできるため、新しい遷移を開始する前に手動でこの処理を行う必要がなくなります。
document.startViewTransition
関数内で型をセットアップすると、オブジェクトを受け入れることができるようになりました。update
は DOM を更新するコールバック関数で、types
は型を含む配列です。
document.startViewTransition({
update: myUpdate,
types: ['slide', 'forwards']
})
複数ページ ビューの切り替え
ウェブの優れた点は、その拡張性にあります。多くのアプリケーションは、単一ページではなく、複数のページを含んだ堅固なタペストリーです。そこで、このたび Chromium 126 で複数ページ アプリケーション向けにドキュメント間のビュー移行をサポートすることになりました。
この新しいクロスドキュメント機能セットには、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(ウェブ ハイパーテキスト アプリケーション テクノロジー ワーキング グループ)など、いくつかの主要な標準化団体やコミュニティ グループが参加する共同の取り組みによって実現されています。
開発者が抱える大きな課題の 1 つは、一見シンプルなリクエストとして、プルダウン メニュー(select 要素)のスタイルを設定できることです。一見単純に見えるかもしれませんが、これは複雑な問題であり、レイアウトやレンダリングから、スクロールと操作、ユーザー エージェントのスタイルや CSS プロパティ、さらには HTML 自体の変更にいたるまで、プラットフォームの多くの要素に関わる問題です。
プルダウンは多数の要素で構成され、以下のような、考慮する必要がある多くの状態が含まれます。
- キーボード バインディング(インタラクションの開始/終了)
- クリックして閉じる
- アクティブなポップオーバー管理(他のポップオーバーが開いたら閉じる)
- タブ フォーカスの管理
- 選択したオプション値を可視化しています
- 矢印インタラクション スタイル
- 状態管理(オープン/クローズ)
現在のところ、この状態をすべて自分で管理するのは困難ですが、このプラットフォームでも簡単に管理することはできません。これを解決するため、これらの部分を分解し、プルダウンのスタイル設定を可能にする基本的な機能をいくつかリリースしますが、他にも多くの機能を提供しています。
Popover API
まず、popover
というグローバル属性をリリースしました。数週間前に Baseline ステータスになりました。
ポップオーバー要素は、ボタンなどの起動元または 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>
ポップオーバー属性を有効にすると、ブラウザは次のようなスクリプトを追加することなく、多くの主要な動作を処理できます。
- 最上位レイヤへのプロモーション: ページの他の部分の上に別のレイヤを表示するため、
z-index
を操作する必要はありません。 - ライトクローズ機能: ポップオーバー領域の外側をクリックすると、ポップオーバーが閉じてフォーカスが戻ります。
- デフォルトのタブ フォーカス管理: ポップオーバーを開くと、そのポップオーバー内で次のタブが停止します。
- 組み込みのキーボード バインディング:
esc
キーを押すか、2 回切り替えると、ポップオーバーが閉じてフォーカスが戻ります。 - デフォルトのコンポーネント バインディング。: ブラウザは、ポップオーバーをトリガーに意味的に関連付けます。
今日では、気づかずにこのポップオーバー API を使用しているかもしれません。GitHub は、ホームページの「新規」メニューと pull リクエスト レビューの概要にポップオーバーを実装しました。Oddbird が開発したポップオーバー ポリフィルを使用してこの機能を段階的に強化し、GitHub 独自の Keith Cirkel のサポートを受けて古いブラウザもサポートしました。
「ポップオーバーに移行することで、文字どおり数千行のコードを廃止できました。ポップオーバーは、魔法の Z-Index と戦う必要性を排除します。...宣言型のボタン動作と正しいアクセシビリティ ツリー関係が確立され、フォーカス動作が組み込まれているため、デザイン システムで正しい方法でパターンを実装しやすくなります。- GitHub、ソフトウェア エンジニア、Keith Cirkel」
開始効果と終了効果のアニメーション化
ポップオーバーがある場合は、インタラクションを追加することをおすすめします。過去 1 年間で、ポップオーバーのアニメーション化をサポートする 4 つの新しいインタラクション機能が追加されました。次のようなものがあります。
キーフレーム タイムラインで display
と content-visibility
をアニメーション化できるようになりました。
transition-behavior
プロパティと allow-discrete
キーワード。display
などの個別のプロパティの遷移を有効にします。
display: none
から最上位レイヤへの入口の効果をアニメーション化する @starting-style
ルール。
アニメーション中の最上位レイヤの動作を制御するオーバーレイ プロパティ。
これらのプロパティは、ポップオーバーでもダイアログでも、最上位レイヤに対してアニメーション化するどの要素に対しても機能します。まとめると、背景付きのダイアログは次のようになります。
デモのビジュアル
ライブデモ
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
を設定して、この要素をアニメーション化するスタイルをブラウザが認識できるようにします。これは、ダイアログと背景の両方で行われます。次に、ダイアログと背景の両方について、開いた状態のスタイルを設定します。ダイアログの場合は open
属性を使用し、ポップオーバーの場合は ::popover-open
疑似要素を使用します。最後に、allow-discrete
キーワードを使用して opacity
、display
、overlay
をアニメーション化し、個別のプロパティが遷移できるアニメーション モードを有効にします。
アンカーの配置
ポップオーバーは物語の始まりにすぎません。大きな更新として、Chrome 125 でアンカーの位置指定がサポートされるようになりました。
アンカーの配置を使用すると、ブラウザはわずか数行のコードで、配置された要素を 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 の記事を参考にした以下のデモでは、下線スタイルは、項目にカーソルを合わせるか、Tab キーで項目にカーソルを合わせると、リストのアイテムに固定されます。
デモのビジュアル
ライブデモ
この例では、アンカー関数を使用し、left
、right
、bottom
の物理プロパティを使用してアンカー位置をセットアップしています。リンクの 1 つにカーソルを合わせると、ターゲットのアンカーが変化します。ブラウザでは、この位置が適用されるようにターゲットが移動します。同時に色もアニメーション化され、見栄えの良いデザインになります。
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
ブロックを作成して、カスタム ID --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;
切り替えを簡単に行うには、これらの flip キーワード値を利用し、position-try
定義の記述を完全にスキップします。これで、わずか数行の CSS だけで、完全に機能する位置情報に対応したアンカー配置の要素を作成できます。
デモのビジュアル
ライブデモ
.tooltip {
inset-area: top;
position-try-options: flip-block;
}
詳しくは、アンカーの配置をご覧ください。
多層 UI の未来
さまざまな場所で利用されるエクスペリエンスが存在しますが、この投稿でご紹介した一連の機能は、創造性を解き放ち、アンカーに配置された要素と階層化されたインターフェースをより適切に制御するための優れた出発点となります。しかし、これはまだ始まりにすぎません。たとえば、現在のところ popover
は、ボタンを呼び出し要素として、または JavaScript でのみ機能します。ウィキペディア スタイルのプレビューのような、ウェブ プラットフォーム全体に見られるパターンでは、マウスオーバーやタブ フォーカスなどをクリックしなくてもリンクやユーザーが興味を示したときに、操作できる必要があります。
ポップオーバー API の次のステップとして、Google は 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 の協力により、Canary でテスト可能なもう一つの今後の一般的な起動元(invoketarget
)があります。invoketarget
は、<dialog>
、<details>
、<video>
、<input type="file">
など、すべてのインタラクティブ要素に対して正規化されたポップオーバーを popovertarget
で提供する宣言型のデベロッパー エクスペリエンスをサポートしています。
<button invoketarget="my-dialog">
Open Dialog
</button>
<dialog id="my-dialog">
Hello world!
</dialog>
ただし、この API でカバーされていないユースケースもあります。たとえば、アンカー要素をアンカーに接続する矢印のスタイルを設定し、特にアンカー要素の位置が変わった場合に、要素を「スライド」して、境界ボックスに到達したときに設定された別の位置にスナップするのではなく、ビューポートにとどまるようにします。Google は、この強力な API を導入できたことを嬉しく思っていますが、将来的にはこの機能をさらに拡張していきたいと考えています。
スタイルを選択可能
チームは popover
と anchor
を組み合わせて使用し、カスタマイズ可能な選択プルダウンを有効にすることを進めてきました。幸いなことに、多くの進歩が見られました。残念ながら、この API は現時点ではまだ試験運用段階です。そこで、ライブデモや進捗状況に関する最新情報を共有し、皆様からのご意見を伺いたいと考えております。
まず、カスタマイズ可能な新しい選択エクスペリエンスにユーザーをオプトインする方法が進展しています。現在実装が進められている方法として、CSS の外観プロパティを 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
で視覚的に非表示にできます。
デモのビジュアル
ライブデモ
selectedoption .text {
display: none;
}
この API で <select>
要素を再利用する最大のメリットの 1 つは、下位互換性です。この国選択では、ユーザーがコンテンツをより簡単に解析できるように、オプションに旗の画像を使用したカスタマイズされた UI が表示されます。サポートされていないブラウザでは、カスタム ボタン、データリスト、選択オプション、オプション内の画像など、理解できない行が無視されるため、フォールバックは現在のデフォルトの選択 UI と同様になります。
カスタマイズ可能な選択機能によって可能性が無限に広がります。この Airbnb スタイルの国セレクターは、レスポンシブ デザインの優れたスタイルを備えているので特に気に入っています。近日発売のスタイル設定可能な選択では、これ以外にも多くのことを行えるため、ウェブ プラットフォームに欠かせない追加機能となっています。
デモのビジュアル
ライブデモ
独占アコーディオン
Chrome チームが注力してきた UI コンポーネントは、一部のスタイル設定(およびそれに付随するすべての要素)の解決だけではありません。最初の追加コンポーネント更新は、排他的なアコーディオンを作成する機能です。これにより、アコーディオン内のアイテムを一度に 1 つだけ開くことができます。
対応ブラウザ
- 120
- 120
- x
- 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
疑似クラスと同じように動作しますが、フォーム コントロールに合致するのは、ユーザーが入力に対してかなりの操作を行った後になります。つまり、フォームの値が操作されたか、「ダーティ」になったかを判断するために必要なコードが大幅に削減されます。これは、ユーザー フィードバックを提供するのに非常に便利であり、これまでこれを行うために必要だった多くのスクリプトを削減できます。
スクリーンキャストのデモ
ライブデモ
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
はテキスト領域で特に便利です。固定サイズに解決されなくなり、小さすぎる入力ボックスにプロンプトの最初の部分に書いた内容を確認するために上にスクロールしなければならなくなる可能性があるためです。
対応ブラウザ
- 123
- 123
- x
- x
スクリーンキャストのデモ
ライブデモ
textarea, select, input {
field-sizing: content;
}
フィールドのサイズ設定の詳細を確認する。
<hr>
in <select>
<hr>
(水平ルール要素)を選択時に有効にできる機能は、小さくても便利なコンポーネント機能です。セマンティックな用途にはあまり使用しませんが、選択リスト内でコンテンツを適切に分離するのに役立ちます。特に、プレースホルダ値など、optgroup でグループ化する必要がないコンテンツについては特に有効です。
スクリーンショットを選択
[ライブデモ] を選択
<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 を使用するをご覧ください。
生活の質の向上
私たちは常にイテレーションを続けており、それはインタラクションとコンポーネントだけの問題ではありません。この 1 年で他にも多くの生活の質(QOL)に関する更新が行われました。
先読みのネスト
ネイティブ CSS のネストは昨年すべてのブラウザで導入され、それ以降、先読みをサポートするよう改善されました。つまり、要素名の前に &
を使用する必要がなくなりました。ネストの雰囲気がずっと人間工学的に優れていて、これまで使っていたものと似ています。
CSS のネストで私が気に入っているのは、コンポーネントを視覚的にブロックできることです。それらのコンポーネントには、コンテナクエリやメディアクエリなどの状態や修飾子が含まれます。以前は、具体性を高めるために、すべてのクエリをファイルの最後にグループ化する習慣がありました。コードの残りの部分のすぐ近くに、わかりやすい方法で書き込むことができます。
.card {
/* card base styles */
h2 {
/* child element style */
}
&.highlight {
/* modifier style */
}
&:hover, &:focus {
/* state styles */
}
@container (width >= 300px) {
/* container query styles */
}
}
ブロック レイアウトのコンテンツの配置
もう一つの非常に便利な変更は、ブロック レイアウトで align-content
などのセンタリング メカニズムを使用できるようになったことです。つまり、これらのレイアウト アルゴリズムで望ましくない、フレックス レイアウトやグリッド レイアウトを適用したり、マージンの折りたたみを防ぐなどの副作用を起こしたりすることなく、div 内で垂直方向の中央揃えを行えるようになりました。
対応ブラウザ
- 123
- 123
- 125
- 17.4
Screenshot
ライブデモ
div {
align-content: center;
}
テキストの折り返し: バランスと見栄え
レイアウトについて言えば、text-wrap: balance
と pretty
の追加により、テキスト レイアウトが大幅に改善されました。text-wrap: balance
はテキスト ブロックの統一に使用され、text-wrap: pretty
はテキストの最終行のシングルトンの削減に重点を置きます。
スクリーンキャストのデモ
ライブデモ
h1 {
text-wrap: balance;
}
詳しくは、text-wrap: Balance をご覧ください。
各国のタイポグラフィのアップデート
CJK テキスト特徴のタイポグラフィ レイアウトの更新では、自然なフレーズ境界で行をラップする word-break: auto-phrase
機能など、過去 1 年間に多くの素晴らしい更新が行われました。
対応ブラウザ
- 119
- 119
- x
- x
text-spacing-trim
は、句読点文字間にカーニングを適用して中国語、日本語、韓国語のタイポグラフィの読みやすさを向上させ、より視覚に訴える結果を実現します。
対応ブラウザ
- 123
- 123
- x
- x
相対色の構文
カラーテーマ設定の世界では、相対カラー構文に関する大きなアップデートがありました。
この例では、Oklch ベースのテーマ設定を使用します。スライダーに基づいて色相値を調整すると、テーマ全体が変更されます。これは相対色の構文で実現できます。背景では、色相に基づいてプライマリ カラーを使用し、明るさ、彩度、色相のチャンネルを調整して値を調整します。--i は、値のグラデーションのリスト内の兄弟インデックスです。これは、ステッピングをカスタム プロパティおよび相対カラー構文と組み合わせてテーマを作成する方法を示しています。
スクリーンキャストのデモ
ライブデモ
: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()
関数の導入に伴い、テーマ設定がより動的になり、簡素化されました。
Adam Argyle によるこの図でわかりやすく示されているように、light-dark()
関数は、カラーテーマ設定オプションを簡素化する人間工学の改善です。これにより、テーマスタイルをより簡潔に記述できます。これまでは、テーマ オプションを設定するには、2 つの異なるコードブロック(デフォルトのテーマとユーザー設定クエリ)が必要でした。light-dark()
関数を使用して、ライトモードとダークモードの両方のスタイル オプションを同じ CSS 行で記述できるようになりました。
html {
color-scheme: light dark;
}
button {
background-color: light-dark(lightblue, darkblue);
}
ユーザーがライトモードを選択した場合、ボタンの背景はライトブルーになります。 ユーザーがダークモードを選択した場合、ボタンの背景は暗い青色になります。
:has()
セレクタ
昨年 12 月にリリースされた :has()
セレクタは、過去 1 年で最も影響力のある相互運用機能であるという点を取り上げずに、最新の UI についてお話しするのはとても残念です。この API は、論理スタイルを記述するための画期的な手段です。
:has()
セレクタを使用すると、子要素に特定の子があるかどうか、それらの子が特定の状態にあるかどうかを確認できます。基本的には、親セレクタとしても機能します。
:has()
は、多くの企業にとって特に有用であることがわかっています。たとえば PolicyBazaar など、PolicyBazaar では、:has()
を使用してブロック内で比較する予定がある場合や空の場合にスタイルを調整するなど、内部コンテンツに基づいてブロックのスタイルを設定しています。
「:has() セレクタのおかげで、JavaScript ベースのユーザー選択検証が不要になり、以前と同じエクスペリエンスでシームレスに機能する CSS ソリューションに置き換えることができました。– Aman Soni 氏、PolicyBazaar テクニカル リーダー」
コンテナクエリ
ウェブに加えられたもう一つの重要な機能がコンテナクエリです。コンテナクエリを使用すると、要素の親の本質的なサイズをクエリしてスタイルを適用できます。これは、ビューポートのサイズのみをクエリするメディアクエリよりもはるかに細い歯のひもです。
Angular は最近、angular.dev で見栄えの良い新しいドキュメント サイトを angular.dev に立ち上げました。コンテナクエリを使用して、ページ上の利用可能なスペースに基づいてヘッダー ブロックのスタイルを設定しています。そのため、レイアウトが変更され、複数列のサイドバー レイアウトから 1 列のレイアウトに変更されても、ヘッダー ブロックは自己調整できます。
コンテナクエリを使用しない場合、このような処理は非常に困難になり、サイズ変更オブザーバーと要素オブザーバーが必要になるため、パフォーマンスに悪影響を及ぼします。親のサイズに基づいて要素のスタイルを設定するのは簡単です。
スクリーンキャストのデモ
ライブデモ
@property
そしてついに、ベースラインに @property が追加される予定です。これは CSS カスタム プロパティ(CSS 変数)にセマンティックな意味をもたらす重要な機能であり、新しいインタラクション機能を数多く実現します。@property
は、CSS でコンテキストの意味、型チェック、デフォルト値、フォールバック値も有効にします。範囲スタイルのクエリなど、さらに堅牢な機能への扉を開く。これまでは不可能だったこの機能で、CSS の言語を深く掘り下げることができるようになりました。
スクリーンキャストのデモ
ライブデモ
@property --card-bg {
syntax: "<color>";
inherits: false;
initial-value: #c0bae8;
}
おわりに
こうした新しいパワフルな UI 機能がさまざまなブラウザで利用できるようになったため、可能性は無限大です。スクロールドリブン アニメーションとビュー遷移による斬新なインタラクティブ エクスペリエンスにより、これまでにない方法でウェブがより滑らかでインタラクティブになります。また、次世代の UI コンポーネントにより、ネイティブ エクスペリエンス全体を損なうことなく、堅牢で美しくカスタマイズされたコンポーネントをこれまで以上に簡単に作成できます。そして最後に、アーキテクチャ、レイアウト、タイポグラフィ、レスポンシブ デザインにおける生活の質の向上により、小さな問題が解消されるだけでなく、さまざまなデバイス、フォーム ファクタ、ユーザーのニーズで動作する複雑なインターフェースを構築するために必要なツールをデベロッパーに提供できます。
これらの新機能により、パフォーマンス重視の機能(アンカー配置によるスクロール表示や要素間のテザリング、滑らかなページ遷移の作成、プルダウンのスタイルの設定、コード全体の構造のネイティブ改善など)のために、サードパーティ スクリプトを削除することが可能になります。
今こそ、ウェブ デベロッパーにとって絶好のタイミングです。CSS3 が発表されて以来、それほど大きな熱意と期待は寄せられていません。私たちが求めていたが、過去に実際に登場することを夢見ていた機能がついに現実のものとなり、プラットフォームの一部になりました。そして、これらの機能を優先し、最終的に実現できるのは、皆様の声のおかげです。Google は、手間のかかる面倒な作業をネイティブで簡単に行えるようにし、ブランドの差別化につながるコア機能やデザインの詳細など、重要なものの構築により多くの時間を割けるようにする取り組みを進めています。
新機能の詳細については、developer.chrome.com や web.dev をご覧ください。ウェブ テクノロジーに関する最新情報を提供しています。スクロールドリブン アニメーション、ビュー遷移、アンカーの位置指定、さらにはスタイル設定可能な選択をお試しいただき、ご意見、ご感想をお寄せください。お客様の声に耳を傾け、サポートさせていただきます。