ウェブの Instagram ストーリーと同様のエクスペリエンスを構築する方法の基本的な概要。
この投稿では、レスポンシブで、キーボード ナビゲーションをサポートし、ブラウザ間で動作するウェブ向けのストーリー コンポーネントの構築に関する考えを共有します。
このストーリー コンポーネントを自分で作成する実践的なデモをご希望の場合は、ストーリー コンポーネントの Codelab をご覧ください。
動画をご覧になる場合は、この投稿の YouTube バージョンをご覧ください。
概要
ストーリー UX の一般的な例として、Snapchat ストーリーと Instagram ストーリー(もちろんフリートも)の 2 つがあります。UX の観点では、ストーリーは通常、モバイル専用のタップ中心のパターンで、複数の定期購入を案内します。たとえば Instagram では、ユーザーが友だちのストーリーを開いて写真を閲覧します。一般的にこれほどの人数で同時に行います。デバイスの右側をタップすると、その友だちの次のストーリーにスキップします。右にスワイプすると、ユーザーは別の友だちに移動します。ストーリー コンポーネントはカルーセルとよく似ていますが、単次元の配列ではなく多次元の配列をナビゲートできます。各カルーセルの中にカルーセルがあるようなものです🤯
ジョブに適したツールの選択
全体として、いくつかの重要なウェブ プラットフォーム機能のおかげで、このコンポーネントはとても簡単に構築できることがわかりました。説明しましょう。
CSS グリッド
私たちのレイアウトは、コンテンツをラングリングするための優れた方法を備えているため、CSS グリッドにとっては必要ない順序ではありません。
友だちのレイアウト
メインの .stories
コンポーネントのラッパーは、モバイルファーストの水平スクロールビューです。
.stories {
inline-size: 100vw;
block-size: 100vh;
display: grid;
grid: 1fr / auto-flow 100%;
gap: 1ch;
overflow-x: auto;
scroll-snap-type: x mandatory;
overscroll-behavior: contain;
touch-action: pan-x;
}
/* desktop constraint */
@media (hover: hover) and (min-width: 480px) {
max-inline-size: 480px;
max-block-size: 848px;
}
grid
レイアウトを細かく見てみましょう。
- モバイルでは明示的に
100vh
と100vw
でビューポートを埋め、パソコンではサイズを制限します。 /
によって行テンプレートと列テンプレートが区切られますauto-flow
はgrid-auto-flow: column
に変換されます- 自動フロー テンプレートは
100%
です。この例では、スクロール ウィンドウの幅は任意です。
スマートフォンでは、行のサイズがビューポートの高さ、各列がビューポートの幅であると考えてください。引き続き Snapchat のストーリーと Instagram のストーリーの例では、各列が友人のストーリーになります。フレンド ストーリーはビューポートの外側でもスクロールできるようにしたいと考えます。グリッドは、友だちのストーリーごとに HTML のレイアウトに必要な数の列を作成し、動的でレスポンシブなスクロール コンテナを作成します。グリッドのおかげで 効果全体を一元化できました
重ね置き
友人ごとに、ページ分け可能な状態でストーリーが必要です。アニメーションやその他の楽しいパターンを準備するために、スタックを選択しました。 スタックとは横からではなく サンドイッチを見下ろしているようなものです
CSS グリッドを使用すると、行と列がエイリアス([story]
)を共有する単一セルのグリッド(正方形)を定義できます。これにより、各子がそのエイリアスの単一セルスペースに割り当てられます。
.user {
display: grid;
grid: [story] 1fr / [story] 1fr;
scroll-snap-align: start;
scroll-snap-stop: always;
}
.story {
grid-area: story;
background-size: cover;
…
}
これにより、HTML がスタック順序を制御するようになり、すべての要素がフローに維持されます。absolute
の位置指定や z-index
については何もする必要はなく、height: 100%
や width: 100%
でボックス修正を行う必要もないことに注目してください。親グリッドによってストーリー画像のビューポートのサイズがすでに定義されているため、ストーリーのどのコンポーネントにもその表示を指示する必要はありません。
CSS スクロール スナップ ポイント
CSS スクロール スナップ ポイントの仕様により、スクロール時に要素をビューポートにロックできるようになりました。こうした CSS プロパティが登場する前は JavaScript を使用しなければならず、控えめに言っても厄介な作業でした。使用方法については、Sarah Drasner による Introducing CSS Scroll Snap Points をご覧ください。
.stories { display: grid; grid: 1fr / auto-flow 100%; gap: 1ch; overflow-x: auto; scroll-snap-type: x mandatory; overscroll-behavior: contain; touch-action: pan-x; }
.user { display: grid; grid: [story] 1fr / [story] 1fr; scroll-snap-align: start; scroll-snap-stop: always; }
スクロールのスナップポイントを選んだ理由はいくつかあります。
- 無料のユーザー補助機能。スクロール スナップ ポイントの仕様では、左矢印キーと右矢印キーを押すと、デフォルトでスナップ ポイント間を移動する必要があると規定されています。
- 拡大する仕様: Scroll Snap Points の仕様は新機能の追加や改善が継続的に行われています。そのため、私のストーリー コンポーネントは今後改善されるでしょう。
- 実装の容易さ。スクロールのスナップ ポイントは、実際には、タップ中心の水平方向のページ分割のユースケース用に構築されています。
- フリー プラットフォーム スタイルの慣性。どのプラットフォームも、スクロールと静止のスタイルが正常であるのに対し、正規化された慣性とは対照的に、それぞれのスタイルでスクロールして静止します。
ブラウザ間の互換性
テストは、Opera、Firefox、Safari、Chrome、Android、iOS で実施しました。ここでは、機能とサポートの違いが見られたウェブ機能の概要を簡単に説明します。
ただし、一部の CSS が適用されていないため、現在一部のプラットフォームでは UX の最適化が行われていません。これらの機能を管理する必要がなく、最終的には他のブラウザやプラットフォームにも導入されることを確信しています。
scroll-snap-stop
カルーセルは、CSS の Scroll Snap Points 仕様を作成するきっかけとなった主要な UX ユースケースの 1 つです。ストーリーとは異なり、カルーセルはユーザーが操作した後に必ずしも各画像で停止する必要はありません。カルーセルをすばやく切り替えてもかまいません。一方、ストーリーは 1 つずつ移動するのが最適です。これが、scroll-snap-stop
が提供するものです。
.user {
scroll-snap-align: start;
scroll-snap-stop: always;
}
この記事の執筆時点では、scroll-snap-stop
は Chromium ベースのブラウザでのみサポートされています。更新については、ブラウザの互換性をご覧ください。ただし、これは阻害要因ではありません。サポートされていないブラウザでは
ユーザーが誤って友だちをスキップしてしまう可能性がありますそのため、ユーザーはより慎重になるか、スキップされた友だちが閲覧済みとしてマークされないように JavaScript を記述する必要があります。
興味があれば、仕様をご覧ください。
overscroll-behavior
モーダルをスクロールしているとき、突然モーダルの背後にあるコンテンツのスクロールが始まったことはありませんか?overscroll-behavior
を使用すると、デベロッパーはスクロールをトラップして、スクロールを離れないようにできます。どんなシチュエーションにもぴったりです。マイ ストーリー コンポーネントは、追加のスワイプやスクロール操作がコンポーネントから離れるのを防ぐために、これを使用します。
.stories {
overflow-x: auto;
overscroll-behavior: contain;
}
Safari と Opera はこれをサポートしなかった 2 つのブラウザで、まったく問題ありません。これまでと同じようにオーバースクロールできるようになり、この機能強化には気付かないかもしれません。私個人は大ファンで オーバースクロール機能のほとんどに取り入れていますこれは UX の改善につながる恐れのある無害な追加です。
scrollIntoView({behavior: 'smooth'})
ユーザーがタップまたはクリックして友だちのストーリー セットの最後に達したら、スクロール スナップ ポイント セット内の次の友だちに移動します。JavaScript では、次の友だちを参照し、それをスクロールするようにリクエストすることができました。基本的なサポートは素晴らしく、どのブラウザもスクロールで表示しています。しかし、'smooth'
、すべてのブラウザがそれに対応しているわけではありません。これは単にスナップされるのではなく、ビューにスクロールされることを意味します。
element.scrollIntoView({
behavior: 'smooth'
})
Safari がここで behavior: 'smooth'
をサポートしなかった唯一のブラウザでした。更新については、ブラウザの互換性をご覧ください。
ハンズオン
さて、やったらどうやってやったの?多様なアプローチとウェブでの構築方法を 学んでいきましょうGlitch を作成して、そのバージョンをツイートしてください。下のコミュニティ リミックス セクションに追加します。
コミュニティのリミックス
- @geoffrich_(Svelte): デモ、コード
- @GauteMeekOlsen(Vue): デモ + コード
- Lit を使用した @AnaestheticsApp: デモとコード