レイアウト変更後のスクロール スナップ

Chrome 81 以降では、強制再スナップのためにイベント リスナーを追加する必要がなくなります。

CSS スクロール スナップを使用すると、ウェブ デベロッパーはスクロール スナップ位置を宣言することで、制御されたスクロール エクスペリエンスを作成できます。現在の実装の欠点の 1 つは、ビューポートのサイズ変更やデバイスの回転など、レイアウトが変更されたときにスクロール スナップがうまく機能しないことです。この欠点は Chrome 81 で修正されています。

相互運用性

多くのブラウザは、CSS スクロール スナップを基本的にサポートしています。詳しくは、CSS スクロール スナップを使用できますか?をご覧ください。

現在、レイアウト変更後のスクロール スナップを実装しているブラウザは Chrome のみです。Firefox では、この実装に関するチケットがオープンしています。また、Safari でも、スクロールバーのコンテンツが変更された後の再スナップに関するチケットがオープンしています。現時点では、次のコードをイベント リスナーに追加して、強制的にスナップを実行することで、この動作をシミュレートできます。 javascript scroller.scrollBy(0,0); ただし、これによってスクロールが同じ要素にスナップバックするとは限りません。

背景

CSS スクロール スナップ

CSS スクロール スナップ機能を使用すると、ウェブ デベロッパーはスクロール スナップ位置を宣言することで、制御されたスクロール エクスペリエンスを作成できます。これらの位置により、スクロール可能なコンテンツがコンテナと適切に位置合わせされ、正確でないスクロールの問題を克服できます。つまり、スクロール スナップは次のようになります。

  • スクロール時にスクロール位置が不自然にならないようにします。
  • コンテンツをページングする効果を作成します。

スクロール スナップの一般的なユースケースは、ページネーションされた記事と画像カルーセルです。

CSS スクロール スナップの例。
CSS スクロール スナップの例。スクロールの終了時に、画像の水平方向の中央がスクロール コンテナの水平方向の中央に配置されます。

欠点

ウィンドウのサイズを変更すると、スナップ位置が失われます。

スクロール スナップを使用すると、ユーザーはコンテンツを簡単に移動できますが、コンテンツやレイアウトの変化に適応できないため、そのメリットを十分に活用できない場合があります。上のに示すように、ユーザーはウィンドウのサイズを変更するたびにスクロール位置を再調整して、以前スナップされた要素を見つける必要があります。レイアウト変更の一般的なシナリオは次のとおりです。

  • ウィンドウのサイズ変更
  • デバイスの回転
  • DevTools を開く

最初の 2 つのシナリオでは、CSS スクロール スナップがユーザーにとって魅力的ではなくなります。3 つ目のシナリオは、デバッグを行っているデベロッパーにとって悪夢です。デベロッパーは、コンテンツの追加、削除、移動などのアクションをサポートする動的エクスペリエンスを作成する場合にも、これらの欠点を考慮する必要があります。

この問題を解決する一般的な方法は、JavaScript を介してプログラムによるスクロールを実行するリスナーを追加し、上記のいずれかのレイアウト変更が発生するたびにスナップを強制的に実行することです。この回避策は、ユーザーがスクロールバーが以前と同じコンテンツにスナップバックすることを想定している場合は効果がありません。JavaScript でさらに処理すると、この CSS 機能の目的がほぼ無意味になるようです。

Chrome 81 で、レイアウト変更後の再スナップが組み込みでサポートされる

上記の欠点は Chrome 81 では解消されています。レイアウトを変更してもスクロールバーはスナップされたままになります。レイアウトを変更した後、スクロール位置を再評価し、必要に応じて最も近いスナップ位置に再スナップします。スクロールバーが、レイアウト変更後に引き続き存在する要素にスナップされていた場合、スクロールバーは元の要素にスナップしようとします。次ので、レイアウトが変更された場合にどうなるかを確認してください。

スナップ位置が失われる
Chrome 80 では、デバイスを回転してもスナップ位置は保持されません。NOPE と表示されているスライドまでスクロールし、デバイスの向きを縦向きから横向きに変更すると、空白の画面が表示されます。これは、スクロール スナップ位置が失われたことを示します。
スナップ位置が保持される
Chrome 81 では、デバイスを回転してもスナップ位置は保持されます。デバイスの向きを何度か変更しても、NOPE と表示されているスライドは表示されたままになります。

詳しくは、レイアウト変更後の再スナップの仕様をご覧ください。

例: 固定スクロールバー

[レイアウト変更後にスナップ] を使用すると、開発者は数行の CSS で固定スクロールバーを実装できます。

.container {
  scroll-snap-type: y proximity;
}

.container::after {
  scroll-snap-align: end;
  display: block;
}

詳しくは、ビジュアルについては、次のデモ チャット UI をご覧ください。

新しいメッセージを追加すると、Chrome 81 で再スナップがトリガーされ、メッセージが下部に固定されます。

今後の作業

現在、すべての再スナップ スクロール エフェクトは即時です。スムーズ スクロール エフェクトによる再スナップをサポートする予定です。詳しくは、仕様に関する問題をご覧ください。

フィードバック

レイアウト変更後の再スナップ機能の改善に役立てるため、ぜひお試しいただき、ご意見を Chromium エンジニアに伝えてください