1. はじめに
このセクションは規範的ではありません。
これは現在、Scroll Snap 1に対する差分仕様です。
スクロール体験は必ずしも最初から始まるとは限りません。カルーセルやスワイプコントロール、リストビューなどの操作は、スクロールコンテナの先頭に位置しない要素から始めることを意図する場合がよくあります。 JavaScriptが必要となり、スクロールコンテナを初期的にその要素までスクロールさせます。CSSで要素を最初にスクロールする指定ができるようにすることで、ユーザー・ページ作者・ブラウザのすべてに利点があります。
初期スクロールターゲットの設定に加えて、開発者はScroll Snapに関する洞察やイベントも必要です。 どの要素がどの軸でスナップされたか、スナップイベントが変化したとき、 スナップが完了したとき、子要素へプログラムでスナップするための利便性などのイベントが求められます。
1.1. 最初のレイアウト
このイベントはアニメーションのコードパスに従うべきです。アニメーションオブジェクトが生成され、イベントが発火する際、ボックスが初めてレイアウトされます。
2. 動機付けとなる例
.carousel{ overflow-inline : auto; } .carousel .origin{ scroll-start-target : auto; }
< div class = "carousel" > < img src = "img1.jpg" > < img src = "img2.jpg" > < img src = "img3.jpg" class = "origin" > < img src = "img4.jpg" > < img src = "img5.jpg" > </ div >
.scrollport{ overflow-block : auto; } main{ scroll-start-target : auto; }
< div class = "scrollport" > < nav > ...</ nav > < main > ...</ main > </ div >
3. スクロール開始位置の設定
3.1. scroll-start-target プロパティ
3.1.1. 初期スクロールターゲット
初期スクロールターゲットは、scroll container scrollcontainerの 'scroll-start-target’プロパティが none 以外に設定されていて、最も近い scroll container が scrollcontainer である要素または疑似要素です。 複数の要素や疑似要素が存在する場合、 ユーザーエージェントはツリー順序で最初に現れるものを選択するべきです。 そのような要素や疑似要素が存在しない場合、scrollcontainerの 初期スクロールターゲットは null です。
-
target を 初期スクロールターゲットとします。
-
position を target に対して スクロールインビュー位置を決定する手順を実行した結果とします。 behavior を "auto"、block を "start"、inline を "nearest"、 scrolling box を scrollcontainer に設定します。
-
scrollcontainer の 初期スクロール位置 に position を設定します。
3.1.2. scroll-start-target プロパティ定義
名前: | scroll-start-target |
---|---|
値: | [ none | auto ] |
初期値: | none |
適用対象: | すべての要素 |
継承性: | no |
パーセンテージ: | N/A |
算出値: | 個々のプロパティ参照 |
正規順序: | 文法に従う |
アニメーション型: | none |
- none
- その要素は初期スクロールターゲットではありません。
- auto
- その要素は最近傍の 初期スクロールターゲットとなる可能性があります。その祖先は scroll containerです。
3.1.3. place-contentとの相互作用
scroll containerの初期スクロール位置が、コンテンツ分布プロパティと、子孫のscroll-start-targetの両方で設定される可能性がある場合、scroll-start-targetが優先されます。
3.1.4. 最初のレイアウト後の到着
文書が更新されている間、 scroll containerの初期スクロールターゲットが、そのscroll containerのレイアウト後に到着することがあります。 この場合、 ユーザーエージェントは、ユーザーが初期スクロール位置へのスクロールに興味がなくなったと考える理由がない限り、 初期スクロールターゲットへスクロールするべきです。
4. スナップされた項目のスタイリング
':snapped' 疑似クラスは、コンテナ状態クエリ手法に置き換えられつつあります。
4.1. スナップ要素疑似クラス: :snapped
:snapped 疑似クラスは、軸を問わず、すべてのスクロールスナップターゲットに一致します。 物理・論理軸ごとのロングフォーム疑似クラスセレクターを使うことで、個々の軸ごとにより細かくスナップされた子要素のスタイリングが可能です。
より具体的なオプションは以下のとおりです:
- :snapped-x
- 水平軸でスナップされた子要素に一致します。
- :snapped-y
- 垂直軸でスナップされた子要素に一致します。
- :snapped-inline
- インライン軸でスナップされた子要素に一致します。
- :snapped-block
- ブロック軸でスナップされた子要素に一致します。
注: Issue #6985
初期フレームの解決方法を検討する必要があります。
5. スナップイベント
5.1. scrollsnapchange
および scrollsnapchanging
CSSスクロールスナップポイントは、スクロールインタラクティブな「選択」コンポーネントを作る仕組みとしてよく使われます。 選択はJavaScriptのintersection observerとスクロール終了の推測で判定されますが、組み込みイベントを用意することで、 これまで見えなかった状態を適切なタイミングで確実にアクション化できるようになります。
5.1.1. スナップターゲット
スナップターゲットは、ユーザーエージェントが 選択して、指定のスナップを行う要素や疑似要素です。スナップコンテナに対して選択されます。
イベント | インターフェース | ターゲット | 説明 |
---|---|---|---|
scrollsnapchange
| SnapEvent
| スクロールコンテナ | スクロール要素またはDocument
で、スクロール終了時(scrollend
イベントの直前)、
またはレイアウトスナップ後に、
スクロール要素やDocumentがスナップされているスナップターゲットが変更された場合に発火します。
|
scrollsnapchanging
| SnapEvent
| スクロールコンテナ | スクロール要素またはDocument
でスクロール中(scroll
イベントの直前)に、
スクロール操作によってスナップされる予定のスナップターゲットが、
直前にscrollsnapchangingイベントが発火したときに選択されていたスナップターゲットと異なる場合に発火します。
|
5.1.2. scrollsnapchange
scrollsnapchange
は、スナップコンテナがどちらかの軸でスナップされたスナップエリアが変更されたことを示します。scrollsnapchange
は以下の場合に発火します:
- スクロール操作が完了した際、ブロック軸またはインライン軸のいずれかで、 スナップコンテナが現在スナップされているスナップターゲットが、直近その軸でスナップされていたスナップターゲットと異なる場合。 proximity厳密度のスナップコンテナでは、スクロールによりどのスナップターゲットにもスナップされなくなる場合があります。 CSS Scroll Snap 1 § 6.2 Choosing Snap Positionsでは、ユーザーエージェントがスナップエリアとなる要素・疑似要素間で選択する方法を説明しています。
- スナップコンテナのスタイルが変更され、none以外の値からscroll-snap-typeの値がnoneになった場合、またはその逆の場合。
- レイアウト変更後に、スナップコンテナがスナップされるスナップターゲットが変更された場合(レイアウト変更後にスクロール位置が変化しなくても該当)。
スクロール操作では必ずscrollend
イベントが発火します。
スクロール操作でscrollsnapchange
イベントも発火する場合は、scrollsnapchange
イベントはscrollend
イベントより先に発火するべきです。
各Document
には、保留中scrollsnapchangeイベントターゲットリストが関連付けられており、初期状態は空です。
各スナップコンテナは、 ブロック軸・インライン軸それぞれに scrollsnapchangeTargetBlock、 scrollsnapchangeTargetInline を持ちます。いずれもその軸でコンテナがスナップされていなければnull、されていればスナップされているスナップターゲットです。
scrollsnapchangeターゲットを更新する場合、snapcontainerについて次の手順を実行します:
-
doc を snapcontainer に関連付けられた
Document
とします。 -
blockTarget を scrollsnapchangeTargetBlockとします。
-
inlineTarget を scrollsnapchangeTargetInlineとします。
-
blockScrollSnapchangingTarget を scrollsnapchanging block軸ターゲットとします。
-
inlineScrollSnapchangingTarget を scrollsnapchanging inline軸ターゲットとします。
-
snap targets changed というブール値フラグを初期値falseで用意します。
-
blockTarget が スナップターゲットとして blockScrollSnapchangingTargetと異なる場合:
-
snapcontainerに関連付けられたscrollsnapchangeTargetBlockをblockScrollSnapchangingTargetに設定します。
-
snap targets changedをtrueに設定します。
-
-
inlineTarget が スナップターゲットとして inlineScrollSnapchangingTargetと異なる場合:
-
snapcontainerに関連付けられたscrollsnapchangeTargetInlineをinlineScrollSnapchangingTargetに設定します。
-
snap targets changedをtrueに設定します。
-
-
snap targets changedがtrueの場合:
-
snapcontainerがdocの保留中scrollsnapchangeイベントターゲットリストにまだ含まれていない場合:
-
snapcontainerをdocの保留中scrollsnapchangeイベントターゲットリストに追加します。
-
-
注: スクロール操作やレイアウト変更でスナップが発生した場合、該当スクローラーのscrollsnapchanging block軸ターゲットおよびscrollsnapchanging
inline軸ターゲットが更新され、現時点のスナップターゲットを表します。これにより、scrollsnapchangeターゲット更新アルゴリズムでこれらスナップターゲットを使ってscrollsnapchange
イベントを発火するかどうか判断できます。
保留中scrollsnapchangeイベントをdispatchする
ために、Document
docについて次の手順を実行します:
-
docの保留中scrollsnapchangeイベントターゲットリスト内の各targetについて:
-
blockTargetおよびinlineTargetを初期値nullで用意します。
-
scrollsnapchangeTargetBlockが疑似要素の場合、 blockTargetにそのscrollsnapchangeTargetBlockの所有要素を設定します。
-
そうでなければ、blockTargetにscrollsnapchangeTargetBlockを設定します。
-
scrollsnapchangeTargetInlineが疑似要素の場合、 inlineTargetにそのscrollsnapchangeTargetInlineの所有要素を設定します。
-
そうでなければ、inlineTargetにscrollsnapchangeTargetInlineを設定します。
-
SnapEvent
snapeventを、scrollsnapchange
という名前でtargetに発火し、snapeventのsnapTargetBlock
属性とsnapTargetInline
属性には、それぞれblockTargetとinlineTargetを設定します。
-
-
docの保留中scrollsnapchangeイベントターゲットリストを空にします。
5.1.3. scrollsnapchanging
scrollsnapchanging
は以下の場合に発火されます:
-
レイアウト変更が発生し、
scrollsnapchange
イベントを発火する必要がある場合。この時はスクロール操作と同様に、scrollsnapchanging
イベントはscrollsnapchange
イベントよりも先に発火されるべきです。
スクロール操作は、特定の位置までアニメーションする場合(例: スクロールバーの矢印クリック、矢印キー操作、"behavior: smooth" のプログラム的スクロール)や、ユーザー入力を直接追従する場合(例: タッチスクロール、スクロールバーのドラッグ)があります。いずれの場合も、ユーザーエージェントは各軸ごとに、スクロール操作が意図したスクロール位置に到達した際に選択される最終的なスナップターゲットを決定します。
-
前者の場合、意図したスクロール位置はスクロールアニメーションのターゲットスクロールオフセットです。
-
後者の場合、意図したスクロール位置はユーザー入力によって決定される現在のスクロールオフセットです。
scrollsnapchanging
は、スクロール操作によってスナップコンテナがスナップされるスナップターゲットが変化することを、できるだけ早い段階でウェブページに知らせることを目的としています。ユーザーエージェントは、scrollsnapchanging
を発火するかどうかを、スクローラーがスクロール操作により意図したスクロール位置に到達した場合に最終的なスナップターゲットにスナップされるかどうかで評価するべきです。
注: scrollsnapchangingは将来のスナッピングに関するヒントをウェブページに与えるため、scrollsnapchangingイベントで示唆されたスナップが実際に発生しない可能性もあります。後続のスクロール入力によって、コンテナのスクロール位置が更に変化し、最終的なスナップターゲットが異なるものになることがあるためです。
scrollsnapchanging
イベントはscroll
イベントよりも先に発火します。
各Document
には、保留中scrollsnapchangingイベントターゲットリストが関連付けられており、初期状態は空です。
各スナップコンテナは、 ブロック軸・インライン軸それぞれに scrollsnapchanging block軸ターゲット、 scrollsnapchanging inline軸ターゲット を持ちます。いずれもその軸でコンテナがスナップされていなければnull、されていればスナップされているスナップターゲットです。
scrollsnapchangingターゲットを更新する場合、snapcontainerについて、新しいブロック軸のスナップターゲットnewBlockTargetと 新しいインライン軸のスナップターゲットnewInlineTargetを与えて、以下の手順を実行します:
-
doc を snapcontainer に関連付けられた
Document
とします。 -
blockTarget を scrollsnapchanging block軸ターゲットとします。
-
inlineTarget を scrollsnapchanging inline軸ターゲットとします。
-
newBlockTarget が スナップターゲットとして blockTargetと異なる場合:
-
snapcontainerに関連付けられたscrollsnapchanging block軸ターゲットをnewBlockTargetに設定します。
-
snapcontainerがdocの保留中scrollsnapchangingイベントターゲットリストに含まれていない場合、
-
snapcontainerをdocの保留中scrollsnapchangingイベントターゲットリストに追加します。
-
-
-
newInlineTarget が スナップターゲットとして inlineTargetと異なる場合:
-
snapcontainerに関連付けられたscrollsnapchanging inline軸ターゲットをnewInlineTargetに設定します。
-
snapcontainerがdocの保留中scrollsnapchangingイベントターゲットリストに含まれていない場合、
-
snapcontainerをdocの保留中scrollsnapchangingイベントターゲットリストに追加します。
-
-
保留中scrollsnapchangingイベントをdispatchする
ために、Document
docについて次の手順を実行します:
-
docの保留中scrollsnapchangingイベントターゲットリスト内の各targetについて:
-
blockTargetおよびinlineTargetを初期値nullで用意します。
-
scrollsnapchanging block軸ターゲットが疑似要素の場合、 blockTargetにそのscrollsnapchanging block軸ターゲットの所有要素を設定します。
-
そうでなければ、blockTargetにscrollsnapchanging block軸ターゲットを設定します。
-
scrollsnapchanging inline軸ターゲットが疑似要素の場合、 inlineTargetにそのscrollsnapchanging inline軸ターゲットの所有要素を設定します。
-
そうでなければ、inlineTargetにscrollsnapchanging inline軸ターゲットを設定します。
-
SnapEvent
snapeventを、scrollsnapchanging
という名前でtargetに発火し、snapeventのsnapTargetBlock
属性とsnapTargetInline
属性には、それぞれblockTargetとinlineTargetを設定します。
-
-
docの保留中scrollsnapchangingイベントターゲットリストを空にします。
5.1.4. レイアウト変更によるスナップイベント
snap container(snapcontainer)が再スナップされる場合、以下の手順を実行します:-
newBlockTarget を snapcontainerがブロック軸でスナップされたスナップターゲット(要素がない場合はnull)とします。
-
newInlineTarget を snapcontainerがインライン軸でスナップされたスナップターゲット(要素や疑似要素がない場合はnull)とします。
-
scrollsnapchangingターゲットを更新する手順をnewBlockTargetおよびnewInlineTargetで実行します。
-
scrollsnapchangeターゲットを更新する手順をsnapcontainerで実行します。
5.2. SnapEvent インターフェース
dictionary :
SnapEventInit EventInit {Node ?;
snapTargetBlock Node ?; }; [
snapTargetInline Exposed =Window ]interface :
SnapEvent Event {(
constructor DOMString ,
type optional SnapEventInit = {});
eventInitDict readonly attribute Node ?snapTargetBlock ;readonly attribute Node ?snapTargetInline ; };
snapTargetBlock
, 型: Node, readonly, null許容-
関連するスナップイベントにおいて、スナップコンテナがブロック軸でスナップ位置にスナップされている要素です。このスナップターゲットが疑似要素だった場合は、その所有要素となります。
snapTargetInline
, 型: Node, readonly, null許容-
関連するスナップイベントにおいて、スナップコンテナがインライン軸でスナップ位置にスナップされている要素です。このスナップターゲットが疑似要素だった場合は、その所有要素となります。
scrollsnapchange
イベントでは、スナップ位置はスクロールスナップ後にコンテナが実現した位置です。scrollsnapchanging
イベントでは、スクロール操作が終わったときコンテナが最終的にスナップされる位置です。
SnapEvent
は、イベントターゲットがDocument
の場合を除き、バブルしません。
SnapEvent
はキャンセル不可です。
付録A: イベントハンドラー
このセクションはHTMLのイベントハンドラー仕様に移動すべきです。
要素・Documentオブジェクト・Windowオブジェクトのイベントハンドラー
以下は、すべてのイベントハンドラー(および対応するイベントハンドラーイベントタイプ)の追加分です。
すべてのHTML要素はイベントハンドラー内容属性およびイベントハンドラーIDL属性としてサポートしなければならず、
すべてのWindow
オブジェクトおよびDocument
オブジェクトも、イベントハンドラーIDL属性としてサポートしなければなりません:
イベントハンドラー | イベントハンドラーイベントタイプ |
---|---|
onscrollsnapchange
| scrollsnapchange
|
onscrollsnapchanging
| scrollsnapchanging
|
GlobalEventHandlers
インターフェースMixinへの拡張
この仕様はHTMLのGlobalEventHandlers
インターフェースMixinを拡張し、
イベントハンドラーIDL属性としてSnapEvent
向けの属性を追加します。
詳細は要素・Documentオブジェクト・Windowオブジェクトのイベントハンドラーを参照してください。
IDL定義
partial interface mixin GlobalEventHandlers {attribute EventHandler ;
onsnapchanged attribute EventHandler ; };
onsnapchanging
6. プライバシーに関する考慮事項
この仕様の機能には、既知のプライバシーへの影響はありません。
7. セキュリティに関する考慮事項
この仕様の機能には、既知のセキュリティへの影響はありません。