2025年、Web制作者がチェックしておきたいCSSの新機能のまとめ: 進化しているインタラクション編
Post on:2025年12月19日
sponsorsr
先日紹介したカスタマイズ可能な新しいコンポーネント編に続いて、2025年、CSSの新機能のまとめ: 進化しているインタラクション編を紹介します。
今年もCSSの進化が早かった1年でした。一昔前にはJavaScriptや複雑なCSSを使用しないとできなかったことがたった一行、もしくは数行のCSSで簡単に実装できるようになりました。

CSS Wrapped 2025 -Google Blog
CSS Wrapped 2025
下記は各ポイントを意訳したものです。
※元サイト様のライセンスとApache 2.0に基づいて翻訳しています。基づいてというのは、貢献部分に関して同ライセンスも含みます。
- はじめに
- インタラクション: scroll-stateクエリ
- インタラクション: ツリーカウント関数
- インタラクション: scrollIntoView()コンテナ
- インタラクション: ネストされたビュー遷移グループ
- インタラクション: iframeと動画をリロードせずにDOM間で移動
はじめに
コンポーネント編に続いて、このインタラクション編ではまさに次世代のインタラクション、ビュー遷移を使用してページ間をアニメーション化したり、美しいスクロールベースのエクスペリエンスなどを紹介します。
新しいAPIを使用すると、複雑な動きをすべて制御し、滑らかでシームレスなユーザーエクスペリエンスを実現できます。
インタラクション: scroll-stateクエリ
scroll-stateクエリは、スクロール可能か、固定されているか、スナップされているか、に基づいて子孫要素のスタイルを設定できます。
要素がスクロール可能か、固定されているか、スナップされているか、を判定するには、これまではJavaScriptを多用するしかできませんでした。さらに、スクロールイベントにタイムアウトを設定する必要があるなど、かなり面倒な作業でした。
Chrome 133+で利用可能なscroll-stateクエリを使用すると、CSSのみでこれらの状態にある要素を宣言的に、より高性能に指定した要素に対してスタイルを設定できます。
スクロール状態クエリを使用するには、要素にcontainer-type: scroll-state;を設定します。
|
1 2 3 |
.parent { container-type: scroll-state; } |
scroll-stateクエリを設定すると、その要素の子要素はその要素がスクロール状態にあるかどうかを照会できるようになります。
- スクロール状態: 要素がオーバーフローしている状態
- スタック状態: 要素が固定されている状態
- スナップ状態: 要素がスナップされている状態
たとえば、スナップされた要素にスタイルを設定するには、scroll-stateクエリのsnappedを使用します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
.scroller { overflow-x: scroll; scroll-snap-type: x mandatory; > div { container-type: scroll-state; scroll-snap-align: center; @supports (container-type: scroll-state) { > * { transition: opacity .5s ease; @container not scroll-state(snapped: x) { opacity: .25; } } } } } |
下記のデモでは、スナップされているアイテムをハイライト表示にします。
See the Pen
CSS Wrapped 2025: scroll-state by coliss (@coliss)
on CodePen.
インタラクション: ツリーカウント関数
リストのアイテムを順番に表示する段階的なアニメーションを作成する一般的な方法は、DOM要素を数え、:nth-childセレクタでこれらの値をプロパティにハードコードする必要があります。この方法は煩雑で、しかも不安定で、特にアイテム数が動的に変化する場合にスケーラブルではありません。
sibling-index()とsibling-count()という新しい関数を使用すると、兄弟要素の中での要素の位置をネイティブに認識し、この問題を解決します。sibling-index()関数は要素の位置を表す1ベースの整数を返し、sibling-count()は兄弟要素の総数を返します。
この2つの関数により、DOM内の要素数に自動的に適応するレイアウトやアニメーションのための簡潔な数学式を記述できるようになります。
|
1 2 3 4 5 6 7 8 9 10 11 12 |
li { /* Create a staggered delay. */ /* We subtract 1 because sibling-index() starts at 1, */ /* ensuring the first item starts immediately (0s). */ transition: opacity 0.25s ease, translate 0.25s ease; transition-delay: calc(0.1s * (sibling-index() - 1)); @starting-style { opacity: 0; translate: 1em 0; } } |
下記のデモは、4枚の画像が交互に表示されるアニメーションです。シャッフルボタンを押すと、順番がランダムになります。
See the Pen
CSS Wrapped 2025: sibling-count(), sibling-index() by coliss (@coliss)
on CodePen.
インタラクション: scrollIntoView()コンテナ
Element.scrollIntoViewのcontainerオプションを使用すると、最も近い親スクロールコンテナのみをスクロールしてscrollIntoViewを実行できます。これはネストされたスクロールコンテナがある場合に非常に便利です。オプションをnearestに設定すると、scrollIntoViewを呼び出しても、すべてのスクロールコンテナがビューポートまでスクロールさせることはありません。
|
1 2 3 4 |
slideList.addEventListener('click', (evt) => { // scrollIntoView will automatically determine the position. evt.target.targetSlide.scrollIntoView({container: 'nearest', behavior: 'smooth'}); }); |
下記のデモでコンテナをnearestに設定した場合と設定しない場合に、ページ途中のカルーセルのドットナビゲーションを操作してscrollIntoViewのアクションを比較してみてください。
See the Pen
CSS Wrapped 2025: scrollIntoView() by coliss (@coliss)
on CodePen.
インタラクション: ネストされたビュー遷移グループ
ネストされたビュー遷移グループはビュー遷移の拡張機能で、::view-transition-group疑似要素を互いにネストできるようにります。
ビュー遷移グループをネストすると、すべてのビュー遷移グループを単一の::view-transition疑似要素の下に兄弟要素として配置するのではなく、遷移中に3D効果やクリッピング効果を維持できます。
別のグループ内に::view-transition-group要素をネストするには、親要素または子要素のいずれかに::view-transition-groupプロパティを設定します。
|
1 2 3 4 5 6 7 8 9 |
.card { view-transition-name: card; overflow: clip; } .card img { view-transition-name: photo; view-transition-group: nearest; } |
ネストされたグループはツリー内の新しい::view-transition-group-children(…)疑似要素内に配置されます。元のDOMで使用されていたクリッピングを復元するには、その疑似要素にoverflow: clip;を設定します。
|
1 2 3 |
::view-transition-group-children(card) { overflow: clip; } |
デモではネストされたビュート遷移グループがない場合、アバターと名前はカードと一緒に回転しません。「3D rotation」のチェックをオンにして、「View Transitions Group」をオン・オフして試してみてください。
See the Pen
CSS Wrapped 2025: ::view-transition-group by coliss (@coliss)
on CodePen.
インタラクション: iframeと動画をリロードせずにDOM間で移動
DOM内で要素を移動するためにinsertBeforeを使用するのは破壊的です。再生中の動画やiframeをinsertBeforeで移動すると、再読み込みされ、状態が完全に失われます。
ただし、Chrome 133+ではmoveBeforeを使用できます。これはinsertBeforeと全く同じように動作しますが、移動中も要素は保持されます。
|
1 2 3 |
const $newSibling = getRandomElementInBody(); const $iframe = document.querySelector('iframe'); document.body.moveBefore($iframe, $newSibling); |
これは、レイアウト上で要素を再配置している最中でも動画の再生は継続され、iframeは再読み込みされず、CSSアニメーションも再開されず、入力フィールドのフォーカスも維持することを意味します。
実際の動作は、デモページでご覧ください。moveBeforeでiframeを移動しても動画は再生され続けます。insertBeforeでiframeを移動すると、iframeがリロードされます。
See the Pen
CSS Wrapped 2025: moveBefore() by coliss (@coliss)
on CodePen.
sponsors











