1. 引言
本节不是规范性内容。
这是目前相对于滚动捕捉 1 的一个增量规范。
滚动体验并不总是从开头开始。与轮播、滑动控制和列表视图的交互往往意图从某个元素开始,这个元素可能并不位于滚动容器的开头。需要使用 JavaScript 使滚动容器最初滚动到该元素。通过使 CSS 能够指定一个元素应当初始滚动到的位置,用户、页面作者和浏览器都能受益。
除了设置初始滚动目标外,开发者还需要对滚动捕捉进行洞察和事件监控。事件包括哪个元素在哪个轴上被捕捉、何时捕捉事件正在变化、何时捕捉完成,以及方便地以编程方式捕捉子元素。
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. 初始滚动目标
初始滚动 目标 是一个 滚动容器 scrollcontainer 的元素或伪元素, 其 'scroll-start-target' 属性不为 none, 并且其最近的 滚动容器 是 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 |
适用: | 所有元素 |
继承: | 否 |
百分比: | 不适用 |
计算值: | 见各个属性 |
规范顺序: | 按语法 |
动画类型: | 无 |
- none
- 该元素不是 初始滚动目标。
- auto
- 该元素可能是其最近的 初始滚动目标,用于其最近的 滚动容器 祖先。
3.1.3. 与 place-content 的交互
如果一个 滚动容器的 初始滚动位置 可能由内容分发属性和 scroll-start-target 在后代中设置,则 scroll-start-target 优先。
3.1.4. 首次布局后的到达
在文档被 更新 时, 滚动容器的 初始滚动目标 可能在该 滚动容器 已布局后到达。 如果发生这种情况, 用户代理仍应滚动到 初始滚动目标,除非用户代理有理由相信 用户不再对滚动到 初始滚动位置 感兴趣。
4. 样式化已捕捉项
':snapped' 伪类正在被淘汰,取而代之的是容器状态查询 方法。
4.1. 已捕捉元素伪类::snapped
:snapped 伪类匹配任何滚动捕捉目标, 无论轴向如何。 详细的物理和逻辑伪类选择器 允许更精细的捕捉子元素样式, 因为它们可以针对特定轴进行选择。
更具体的选项定义如下:
- :snapped-x
- 匹配在水平轴上已捕捉的子元素。
- :snapped-y
- 匹配在垂直轴上已捕捉的子元素。
- :snapped-inline
- 匹配在行内轴上已捕捉的子元素。
- :snapped-block
- 匹配在块轴上已捕捉的子元素。
注意: 问题 #6985
需要
确定初始帧的解决方案。
5. 捕捉事件
5.1. scrollsnapchange
和 scrollsnapchanging
CSS 滚动捕捉点通常用作 创建滚动交互“选择”组件的机制, 选择通过 JavaScript 交叉观察者 和滚动结束估算来确定。通过创建内置事件, 隐藏状态将变为可操作, 在合适的时机,并始终正确。
5.1.1. 捕捉目标
一个 捕捉目标 是一个元素 或伪元素,用户代理已选择来捕捉 给定的捕捉容器。
事件 | 接口 | 目标 | 描述 |
---|---|---|---|
scrollsnapchange
| SnapEvent
| 滚动容器 | 在滚动元素或文档
的滚动结束时触发(在scrollend
事件之前)
或在布局捕捉之后触发,如果捕捉目标与
滚动元素或文档所捕捉的目标发生了变化。
|
scrollsnapchanging
| SnapEvent
| 滚动容器 | 在滚动元素或文档
滚动期间触发(在scroll
事件之前),
如果捕捉目标
导致滚动器捕捉的目标与上一个
滚动捕捉更改事件触发时所选择的捕捉目标不同。
|
5.1.2. scrollsnapchange
scrollsnapchange
表示快照容器在任一轴线上快照的快照区域已发生变化。scrollsnapchange
在以下情况下被派发:
- 当滚动操作完成时,如果在块轴或行内轴上,快照容器所快照的快照目标与该轴上最近快照的快照目标不同。对于具有邻近严格性的快照容器,滚动可能导致快照容器不再快照到任何快照目标。CSS Scroll Snap 1 § 6.2 选择快照位置描述了用户代理在选择元素或伪元素时所遵循的方法,这些元素或伪元素是快照区域。
- 如果快照容器的样式发生变化,使其从具有非无值的scroll-snap-type变为有值,或者反之亦然。
- 如果在布局变化后,快照容器所快照的快照目标发生变化,无论布局变化后滚动位置是否发生变化。
滚动操作总是会导致触发scrollend
事件。如果一次滚动操作还导致触发scrollsnapchange
事件,则scrollsnapchange
事件应在scrollend
事件之前触发。
每个Document
都有一个关联的待处理的scrollsnapchange 事件目标列表,初始为空。
每个快照容器在块轴和行内轴上各有一个scrollsnapchangeTargetBlock和一个scrollsnapchangeTargetInline,每个可以是null,如果容器在该轴上未被快照,或者是快照目标,即容器所快照的目标。
当被要求为快照容器(snapcontainer)更新 scrollsnapchange 目标时,执行以下步骤:
-
让doc成为snapcontainer的关联
Document
。 -
让blockTarget成为与snapcontainer关联的scrollsnapchangeTargetBlock。
-
让inlineTarget成为与snapcontainer关联的scrollsnapchangeTargetInline。
-
让blockScrollSnapchangingTarget成为与snapcontainer关联的scrollsnapchanging block-axis target。
-
让inlineScrollSnapchangingTarget成为与snapcontainer关联的scrollsnapchanging inline-axis target。
-
让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-axis target和scrollsnapchanging inline-axis
target会被更新,并表示该滚动器的当前快照目标。这允许更新scrollsnapchange目标算法使用这些快照目标来确定是否应该触发scrollsnapchange
事件。
当被要求为调度待处理的scrollsnapchange事件时,对于Document
,doc,执行以下步骤:
-
对于doc的待处理的scrollsnapchange事件目标中的每个项target:
-
初始时让blockTarget和inlineTarget都为null。
-
如果与target关联的scrollsnapchangeTargetBlock是一个伪元素,则将blockTarget设置为该scrollsnapchangeTargetBlock的拥有元素。
-
否则,将blockTarget设置为该scrollsnapchangeTargetBlock。
-
如果与target关联的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-axis target和一个scrollsnapchanging inline-axis target,每个都可以为null(如果容器在该轴上不进行快照),或者是该容器所快照的快照目标。
当被要求为快照容器,snapcontainer,更新scrollsnapchanging目标时,给定一个快照目标 newBlockTarget和一个快照目标 newInlineTarget,执行以下步骤:
-
让doc为snapcontainer的相关
Document
。 -
让blockTarget为与snapcontainer关联的scrollsnapchanging block-axis target。
-
让inlineTarget为与snapcontainer关联的scrollsnapchanging inline-axis target。
-
如果newBlockTarget与blockTarget不是同一个快照目标:
-
将与snapcontainer关联的scrollsnapchanging block-axis target设置为newBlockTarget。
-
如果snapcontainer尚未在doc的pending scrollsnapchanging event targets中,
-
将snapcontainer附加到doc的pending scrollsnapchanging event targets
-
-
-
如果newInlineTarget与inlineTarget不是同一个快照目标:
-
将与snapcontainer关联的scrollsnapchanging inline-axis target设置为newInlineTarget。
-
如果snapcontainer尚未在doc的pending scrollsnapchanging event targets中,
-
将snapcontainer附加到doc的pending scrollsnapchanging event targets。
-
-
当要求为一个Document
doc 分派待处理的scrollsnapchanging事件时,执行以下步骤:
-
对于doc的待处理的scrollsnapchanging事件目标中的每个项target:
-
最初将blockTarget和inlineTarget设为null。
-
如果与target关联的scrollsnapchanging块轴目标是一个伪元素,将blockTarget设置为该scrollsnapchanging块轴目标的拥有元素。
-
否则,将blockTarget设置为该scrollsnapchanging块轴目标。
-
如果与target关联的scrollsnapchanging行内轴目标是一个伪元素,将inlineTarget设置为该scrollsnapchanging行内轴目标的拥有元素。
-
否则,将inlineTarget设置为该scrollsnapchanging行内轴目标。
-
在target上触发一个名为
scrollsnapchanging
的SnapEvent
,让snapevent的snapTargetBlock
和snapTargetInline
属性分别为blockTarget和inlineTarget。
-
-
清空doc的待处理的scrollsnapchanging事件目标。
5.1.4.因布局变化而触发的 Snap 事件
当一个snap container snapcontainer 重新对齐时,执行以下步骤:-
让newBlockTarget为snapcontainer在块轴上已对齐到的 snap 目标,如果未对齐到任何元素,则为 null。
-
让newInlineTarget为snapcontainer在行内轴上已对齐到的 snap 目标,如果未对齐到任何元素或伪元素,则为 null。
-
使用newBlockTarget作为 newBlockTarget 和newInlineTarget作为 newInlineTarget,执行更新 scrollsnapchanging 目标的步骤。
-
为snapcontainer执行更新 scrollsnapchange 目标的步骤。
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,只读,允许为 null-
在与该 snap 事件相关联的snap 位置上,snap 容器在块轴上对齐到的元素。如果与此对应的snap 目标是伪元素,则这是该伪元素的拥有元素。
snapTargetInline
, 类型为 Node,只读,允许为 null-
在与该 snap 事件相关联的snap 位置上,snap 容器在行内轴上对齐到的元素。如果与此对应的snap 目标是伪元素,则这是该伪元素的拥有元素。
对于scrollsnapchange
事件,snap
位置是 snap 容器在 scroll snap 之后已实现的位置。对于scrollsnapchanging
事件,snap
位置是 scroll 操作结束后 snap 容器将最终对齐的位置。
SnapEvent
不会冒泡,除非事件目标是Document
。SnapEvent
不可取消。
附录 A:事件处理程序
本节应移至 HTML 事件处理程序规范。
元素、文档对象和窗口对象上的事件处理程序
以下是所有事件处理程序(及其相应的事件处理程序事件类型),这些必须被所有HTML 元素支持,作为事件处理程序内容属性和事件处理程序 IDL 属性;并且所有Window
对象和Document
对象也必须支持这些作为事件处理程序 IDL 属性:
事件处理程序 | 事件处理程序事件类型 |
---|---|
onscrollsnapchange
| scrollsnapchange
|
onscrollsnapchanging
| scrollsnapchanging
|
对
GlobalEventHandlers
接口混合的扩展
本规范扩展了来自 HTML 的 GlobalEventHandlers
接口混合,为 SnapEvent
添加 事件处理 IDL 属性,如元素、文档对象和窗口对象上的事件处理程序中所定义。
IDL 定义
partial interface mixin GlobalEventHandlers {attribute EventHandler ;
onsnapchanged attribute EventHandler ; };
onsnapchanging
6. 隐私考虑
本规范中的功能没有已知的隐私影响。
7. 安全考虑
本规范中的功能没有已知的安全影响。