1. 引言
本节不具有规范性。
可滚动内容的流行用户体验(UX)范式经常采用内容分页或将其划分为逻辑分区。这在触控交互中尤为重要,因为用户通过在平铺的内容广度上快速平移,比通过点击导航深入层级结构更快捷、更容易。例如,用户通过平移照片幻灯片视图查看相册中的多张照片,比点击相册中的单张照片更容易。
然而,考虑到触控平移和鼠标滚轮滚动等滚动输入的不精确性,网页开发者很难保证受控良好的滚动体验,特别是在创建分页内容效果时。例如,用户很容易停在一个尴尬的滚动位置,导致平移时某个项目只显示了一部分。
为此,本模块引入了滚动吸附位置,这些位置强制执行滚动容器的滚动口在滚动操作完成后可能停下的位置。
此外,为了在关闭吸附功能时也能提供更好的分页和滚动定位控制,本模块为所有滚动容器定义了 scroll-padding 属性,用于调整滚动容器的最佳观看区域,以实现分页和滚动进入视图的操作。同样,scroll-margin 属性可用于任何盒子,以调整其视觉区域,用于滚动进入视图的操作。
1.1. 模块交互
本模块扩展了 [CSS2] 第 11.1 节中定义的滚动用户界面功能。
本模块中的任何属性都不适用于 ::first-line 和 ::first-letter 伪元素。
1.2. 值的定义
本规范遵循 CSS 属性定义约定([CSS2]),使用 值定义语法([CSS-VALUES-3])。本规范未定义的值类型在 CSS Values & Units [CSS-VALUES-3] 中定义。与其他 CSS 模块的组合可能会扩展这些值类型的定义。
除了定义中列出的属性特定值外,本规范中定义的所有属性也都接受 CSS 全局关键字 作为其属性值。为了可读性,未明确重复列出。
2. 激励性示例
img{ /* Specifies that the center of each photo should align with the center of the scroll container in the X axis when snapping */ scroll-snap-align: none center; } .photoGallery{ width : 500 px ; overflow-x : auto; overflow-y : hidden; white-space : nowrap; /* Requires that the scroll position always be at a snap position when the scrolling operation completes. */ scroll-snap-type: x mandatory; }
< div class = "photoGallery" > < img src = "img1.jpg" > < img src = "img2.jpg" > < img src = "img3.jpg" > < img src = "img4.jpg" > < img src = "img5.jpg" > </ div >
.page{ /* Defines the top of each page as the edge that should be used for snapping */ scroll-snap-align: start none; } .docScroller{ width : 500 px ; overflow-x : hidden; overflow-y : auto; /* Specifies that each element’s snap area should align with a 100px offset from the top edge. */ scroll-padding:100 px 0 0 ; /* Encourages scrolling to end at a snap position when the operation completes, if it is near a snap position */ scroll-snap-type: y proximity; }
< div class = "docScroller" > < div class = "page" > Page 1</ div > < div class = "page" > Page 2</ div > < div class = "page" > Page 3</ div > < div class = "page" > Page 4</ div > </ div >
3. 滚动吸附模型
本模块定义了滚动吸附位置的控件,这些位置是产生滚动容器内特定内容对齐方式的滚动位置。通过在相关滚动容器上使用 scroll-snap-type 属性,作者可以要求滚动口在滚动操作(包括编程滚动,如 scrollTo() 方法)后停在吸附位置上的特定倾向。
吸附位置被指定为元素滚动吸附区域(其边框盒,由 scroll-margin 修改)在滚动容器的滚动吸附口(其滚动口,由 scroll-padding 缩减)内的特定对齐方式(scroll-snap-align)。这在概念上等同于指定对齐主体在对齐容器内的对齐方式。满足指定对齐方式的滚动位置即为吸附位置。
调整滚动容器的滚动口位置使其与吸附位置对齐的行为称为吸附;如果滚动口的滚动位置为该吸附位置且没有正在进行的滚动操作,则称滚动容器已吸附到该吸附位置。CSS 滚动吸附模块特意不指定也不强制要求执行吸附位置所需的任何精确动画或物理效果;这留给用户代理决定。
4. 捕获滚动吸附区域:滚动容器上的属性
4.1. 滚动吸附规则:scroll-snap-type 属性
| 名称 | scroll-snap-type |
|---|---|
| 值 | none | [ x | y | block | inline | both ] [ mandatory | proximity ]? |
| 初始值 | none(无) |
| 应用于 | 所有元素 |
| 可继承 | 否 |
| 百分比 | 不可用 |
| 计算值 | 指定的关键字 |
| 规范顺序 | 按语法 |
| 动画类型 | 离散 (discrete) |
scroll-snap-type 属性指定滚动容器是否为滚动吸附容器、其吸附严格度以及考虑哪些轴。如果未指定严格度值,则假定为 proximity。
html {
scroll-snap-type: block; /* applied to main document scroller */
}
h1, h2, h3, h4, h5, h6 {
scroll-snap-align: start; /* snap to the start (top) of the viewport */
}
用户代理必须将根元素上设置的 scroll-snap-type 值应用于文档视口。注意,与 overflow 不同,scroll-snap-type 值不会从 HTML body 传播。
4.1.1. 滚动吸附轴:x, y, block, inline 和 both 值
轴值指定受吸附位置影响的轴,以及吸附位置是按轴独立评估还是作为 2D 点整体评估。各值定义如下:
- x
- 滚动容器仅在其水平轴上吸附到吸附位置。
- y
- 滚动容器仅在其垂直轴上吸附到吸附位置。
- block
- 滚动容器仅在其块轴上吸附到吸附位置。
- inline
- 滚动容器仅在其内联轴上吸附到吸附位置。
- both
- 滚动容器在两个轴上独立吸附到吸附位置(可能在每个轴上吸附到不同的元素)。
4.1.2. 滚动吸附严格度:none, proximity 和 mandatory 值
严格度值(none, proximity, mandatory)指定在滚动容器上强制执行吸附位置的严格程度(通过强制调整滚动位置)。各值定义如下:
- none(无)
- 如果指定在滚动容器上,则滚动容器不得吸附。
- mandatory
- 如果指定在滚动容器上,则要求滚动容器在没有进行中的滚动操作时必须吸附到吸附位置。如果存在有效的吸附位置,则滚动容器必须在滚动结束时吸附(如果不存在,则不发生吸附)。
- proximity
- 如果指定在滚动容器上,则滚动容器可以在滚动结束时由 UA 根据滚动参数自行决定是否吸附到吸附位置。
作者在使用强制吸附位置时应考虑不同尺寸的屏幕以及(如果适用)不同尺寸的内容。特别是,尽管对大于滚动口的被吸附元素的访问由 UA 处理,但如果作者将强制吸附分配给非相邻的兄弟元素,当内容长度超过屏幕时,中间的内容可能会变得无法访问。
如果一个盒子是滚动容器或者 scroll-snap-type 的值不为 none,则该盒子捕获吸附位置。如果一个盒子的包含块链上最近的吸附位置捕获祖先是一个滚动容器,且其 scroll-snap-type 的值为非 none,则该祖先为该盒子的滚动吸附容器。否则,该盒子没有滚动吸附容器,其吸附位置不会触发吸附。
4.1.3. 布局更改后的重新吸附
如果文档的内容或布局发生更改(例如内容被添加、移动、删除、调整大小),导致滚动吸附口的内容发生变化,UA 必须重新评估由此产生的滚动位置,并在需要时重新吸附。如果滚动容器在内容更改前已吸附,且该相同的吸附位置仍然存在(例如其关联元素未被删除),则内容更改后,滚动容器必须重新吸附到该相同的吸附位置。如果多个盒子在之前已吸附且它们的吸附位置不再重合,则如果其中一个已获得焦点或成为目标,滚动容器必须重新吸附到该盒子;否则,重新吸附到哪一个由 UA 定义。(例如,随着布局的移动导致其他元素的吸附位置对齐和失对齐,UA 可以跟踪当前吸附的元素。)
由于重新吸附操作而导致的向新盒子或不同盒子的滚动,必须表现和动画化得与其他任何“滚动进入视图”操作一样,包括遵循 scroll-behavior 等控件。然而,重新吸附到与之前相同的盒子的滚动行为由 UA 定义。例如,当吸附到某个部分的开始处时,如果文档较早部分动态添加了内容,UA 可能选择不对滚动到该部分新位置的过程进行动画处理,以营造没有滚动的错觉。
.log{ scroll-snap-type : proximity; align-content : end; } .log::after{ display : block; content : "" ; scroll-snap-align : end; }
这些规则创建了一个单一的滚动吸附区域,由 ::after 伪元素表示,定位在滚动吸附容器的最底部。如果用户滚动到“靠近”底部的位置,容器将吸附到该位置。如果更多内容被动态添加到容器中,它将保持吸附状态(因为如果滚动吸附区域在更改后仍然存在,滚动容器被要求重新吸附到相同的区域)。然而,如果用户已经滚动到日志的其他位置,它将不会执行任何操作。
4.2. 滚动吸附口:scroll-padding 属性
| 名称 | scroll-padding |
|---|---|
| 值 | [ auto | <length-percentage> ]{1,4} |
| 初始值 | auto |
| 应用于 | 滚动容器 |
| 可继承 | 否 |
| 百分比 | 相对于滚动容器滚动口的相应维度 |
| 计算值 | 每侧可以是关键字 auto 或计算出的 <length-percentage> 值 |
| 动画类型 | 按计算值类型 |
| 规范顺序 | 按语法 |
此属性指定(针对所有滚动容器,而不仅是滚动吸附容器)定义滚动口最佳观看区域的偏移量:即作为将对象置于用户视野内的目标区域。这允许作者排除滚动口中被其他内容(如固定定位的工具栏或侧边栏)遮挡的区域,或者仅仅是在目标元素和滚动口边缘之间留出更多呼吸空间。
scroll-padding 属性是一个简写属性,可以在一个声明中设置所有 scroll-padding-* 完整属性,并按照 padding 属性为其完整属性赋值的方式,为代表每一侧的完整属性分配值。各值的含义如下:
- <length-percentage>
-
定义从滚动口相应边缘向内的偏移量。当应用于根视口时,该偏移量的计算和应用相对于布局视口(而非视觉视口),方式与固定定位盒子上的相应插入属性相同;最佳观看区域是与视觉视口相交的剩余区域。
- auto
-
表示滚动口相应边缘的偏移量由 UA 确定。这通常应默认为 0px 的使用长度,但 UA 可以使用启发式方法检测何时非零值更为合适。
这些偏移量减少了对于滚动操作而言被认为是“可视”的滚动口区域:它们对布局、滚动原点或初始位置,或元素是否被实际认为是可见的没有影响,但应该会影响元素或插入符号是否被视为已滚动到视图中(例如用于定位或聚焦操作),并减少分页操作(例如使用 PgUp 和 PgDn 键或从滚动条触发等效操作)的滚动量,以便用户在滚动口的最佳观看区域内看到连续的内容流。
对于滚动吸附容器,此区域还定义了滚动吸附口——即在计算吸附位置时,用作滚动吸附区域的对齐容器的滚动口区域。
html{ overflow-x : auto; overflow-y : hidden; scroll-snap-type : x mandatory; scroll-padding : 0 500 px 0 0 ; } .toolbar{ position : fixed; height : 100 % ; width : 500 px ; right : 0 ; } img{ scroll-snap-align : none center; }
用户代理必须将根元素上设置的 scroll-padding 值应用于文档视口。(注意,与 overflow 不同,scroll-padding 值不会从 HTML body 传播。)
5. 对齐滚动吸附区域:元素上的属性
5.1. 滚动吸附区域:scroll-margin 属性
| 名称 | scroll-margin |
|---|---|
| 值 | <length>{1,4} |
| 初始值 | 0 |
| 应用于 | 所有元素 |
| 可继承 | 否 |
| 百分比 | 不可用 |
| 计算值 | 每侧一个绝对长度 |
| 规范顺序 | 按语法 |
| 动画类型 | 按计算值类型 |
此属性是一个简写属性,可以在一个声明中设置所有 scroll-margin-* 完整属性,并按照 margin 属性为其完整属性赋值的方式,为代表每一侧的完整属性分配值。
这些值表示定义用于将此盒子吸附到吸附口的滚动吸附区域的外延量。滚动吸附区域的确定方法是:获取变换后的边框盒,找到其矩形边界盒(在滚动容器的坐标空间中轴对齐),然后添加指定的外延量。
注:这确保了滚动吸附区域始终是矩形的,且与滚动容器的坐标空间轴对齐。
如果页面导航到一个定义了目标元素的片段(即可以被 :target 匹配,或者是 scrollIntoView() 的目标),UA 应使用该元素的滚动吸附区域,而不是仅仅使用其边框盒,来决定将可滚动溢出区域的哪个部分带入视图,即使在吸附功能关闭或未应用于此元素时也是如此。
5.2. 滚动吸附对齐:scroll-snap-align 属性
| 名称 | scroll-snap-align |
|---|---|
| 值 | [ none | start | end | center ]{1,2} |
| 初始值 | none(无) |
| 应用于 | 所有元素 |
| 可继承 | 否 |
| 百分比 | 不可用 |
| 计算值 | 两个关键字 |
| 规范顺序 | 按语法 |
| 动画类型 | 离散 (discrete) |
scroll-snap-align 属性将盒子的吸附位置指定为,其吸附区域(作为对齐主体)在其吸附容器的吸附口(作为对齐容器)内的对齐方式。两个值分别指定在块轴和内联轴上的吸附对齐,具体由吸附容器的书写模式决定。如果只指定一个值,第二个值默认为相同的值。
值定义如下
- none
- 此盒子在指定轴上不定义吸附位置。
- start
- 此盒子滚动吸附区域在滚动容器的吸附口内的起始对齐,即为指定轴上的吸附位置。
- end
- 此盒子滚动吸附区域在滚动容器的吸附口内的结束对齐,即为指定轴上的吸附位置。
- center
- 此盒子滚动吸附区域在滚动容器的吸附口内的居中对齐,即为指定轴上的吸附位置。
起始和结束对齐方式是根据吸附容器的书写模式来解析的,除非滚动吸附区域大于吸附口,在这种情况下,它们根据盒子本身的书写模式来解析。(这允许容器中的项目在总体上具有一致的吸附对齐,同时确保 start 始终将项目对齐,以便从头开始阅读其内容。)
5.2.1. 将有效吸附位置的作用域限定于可见盒子
由于滚动吸附的目的是为了最佳观看效果而在滚动口内对齐内容,因此如果吸附到某个位置会导致贡献该位置的吸附区域完全处于吸附口之外,即使它以其他方式满足了该吸附区域所需的对齐方式,该滚动位置也不被视为有效的吸附位置。
╔════viewport════╗┈┈┈┈┈┈┈┈┌──────────────┐
║ ┌─────┐ ┌──┐ ║ │ top-snapping │
║ ├──┐ │ └──┘ ║ │ element │
║ └──┴──┘ ║ │ │
╚════════════════╝ │ │
└──────────────┘
为什么要将吸附限制在元素可见时?
正如 WebKit 实现者指出的那样,在画布上无限延伸吸附边缘只允许吸附网格布局,并且当屏幕外元素与屏幕内元素不对齐时,会给用户产生奇怪的行为。(如果这对实现者来说太困难,我们可以默认为网格行为,以后再引入切换以获得更智能的行为。)注:虽然 scroll-snap-type: both 独立评估每个轴上的吸附位置,但在一个轴上选择吸附位置可能会受到另一个轴上吸附位置的影响。例如,在一个轴上的吸附可能会将另一个轴本应吸附到的吸附区域推到屏幕外,使其吸附位置失效,从而无法选择。
5.2.2. 吸附溢出滚动口的盒子
如果吸附区域在特定轴上大于吸附口,则任何吸附区域覆盖吸附口,且该轴上几何意义上的前一个和后一个吸附位置之间的距离大于该轴上吸附口尺寸的滚动位置,在该轴上均是有效的吸附位置。UA 可以将指定的对齐方式用作某些滚动操作(例如显式分页)的更精确目标。
由于吸附区域大于吸附口,而该区域完全填充了滚动口,因此容器可以任意滚动,并且不会尝试吸附回其对齐位置。然而,如果容器被滚动使得该区域在一个轴上不再完全填充滚动口,则该区域会抵抗向外滚动,直到它被滚动到足以触发吸附到不同的吸附位置为止。
section 元素上的强制顶部吸附可能会产生大的吸附区域(来自大的顶级部分),这些区域中可能填充了较小的吸附区域(来自小节)。当小节足够小时,它们正常吸附;当它们更长时,查看者可以在它们内部任意滚动,或者在顶级部分的某个大片段内滚动,该片段没有任何小节可供吸附。┌─ top-level section ─┐ ━┓ │ │ 1┃ │ │ ┃ │ │ ━┩ │ │ ┆ │ │ ┆ │┌─── sub-section ───┐│ ╯ ━┓ │└───────────────────┘│ 2┃ │┌─── sub-section ───┐│ ━┓ ┃ ││ ││ 3┃ ━┛ │└───────────────────┘│ ┃ │┌─── sub-section ───┐│ ━┛ ━┓ │└───────────────────┘│ 4┃ │┌─── sub-section ───┐│ ━┓ ┃ ││ ││ 5┃ ━┛ ││ ││ ┃ ││ ││ ━┩ ││ ││ ┆ ││ ││ ┆ ││ ││ ┆ │└───────────────────┘│ ┆ └─────────────────────┘ ╯
注:如果作者改而在每个部分的标题(而不是部分本身)上设置强制吸附位置,那么第一和第五部分的内容将部分无法被用户访问,因为标题吸附区域没有延伸到覆盖整个部分。这就是为什么在可能间隔很远的元素上使用强制吸附位置是一个糟糕的想法。
5.2.3. 无法到达的吸附位置
如果一个吸附位置如上所述是无法到达的,即对齐到该位置需要将滚动容器的滚动口滚动到超出其可滚动溢出区域的边缘,则此吸附区域的使用吸附位置是在每个相关轴上朝向期望的吸附位置滚动尽可能多后得到的位置。
5.3. 滚动吸附限制:scroll-snap-stop 属性
| 名称 | scroll-snap-stop |
|---|---|
| 值 | normal | always |
| 初始值 | normal |
| 应用于 | 所有元素 |
| 可继承 | 否 |
| 百分比 | 不可用 |
| 计算值 | 指定关键字 |
| 规范顺序 | 按语法 |
| 动画类型 | 离散 (discrete) |
当沿预期方向滚动时,滚动容器可以在到达滚动操作的自然终点并选择其最终滚动位置之前,“越过”多个可能的吸附位置(如果滚动操作使用了相同的方向但距离较短,这些位置本可以有效吸附)。scroll-snap-stop 属性允许这样一个可能的吸附位置“拦截”滚动操作,强制滚动容器在滚动操作自然结束前停止。
值定义如下
- normal
- 滚动容器在滚动操作执行期间可以越过由该元素定义的吸附位置。
- always
- 滚动容器在滚动操作执行期间不得越过由该元素定义的吸附位置;它必须吸附到该元素第一个吸附位置。
此属性对仅具有预期终点位置的滚动操作没有影响,因为它们在概念上不会“越过”任何吸附位置。
6. 吸附机制
选择要吸附到的吸附位置的精确模型算法被刻意留为大部分未定义,以便用户代理可以考虑到对用户意图和交互的复杂建模,并随着时间的推移调整其响应方式,以最好地服务于用户。
本节定义了一些有用的概念来帮助讨论滚动吸附机制,并为有效的滚动吸附策略应该是什么样提供了一些指导原则。鼓励用户代理在定义自己的吸附行为时采用这些指导并运用自己的最佳判断。它还提供少量行为要求,以确保作者在考虑滚动吸附设计界面时可以依赖的最低限度的合理行为。
6.1. 滚动方法类型
当页面被滚动时,该动作以预期的终点位置和/或预期的方向执行。这两者的每一种组合都定义了一种独特的滚动类别,可以进行略有不同的处理:
- 预定结束位置
-
仅具有预期终点位置的滚动常见示例包括:
-
平移手势,释放时无惯性
-
显式操作滚动条“滑块”
-
通过诸如
scrollTo()等 API 以编程方式滚动 -
通过文档的可聚焦元素进行 Tab 导航
-
导航到页面内的锚点
-
归位操作,如 Home/End 键
-
- 预定方向和结束位置
-
在吸附点等功能介入之前的滚动预期终点为其自然终点。
- 预定方向
此外,因为页面布局通常在垂直和/或水平方向上对齐事物,所以 UA 有时会在滚动方向足够垂直或水平时对滚动进行轴锁定。轴锁定滚动仅被绑定在该轴上滚动。这可以防止不太精确的输入机制在非主轴上产生漂移。
注:本规范仅适用于用户代理支持的滚动方法;它不要求用户代理支持任何特定的输入或滚动方法。
6.2. 选择吸附位置
滚动容器可以在其可滚动溢出区域内散布许多吸附区域。一种简单的选择吸附位置的算法可能会产生对用户来说不直观的行为,因此在设计选择算法时需要格外小心。以下是一些有助于选择过程的提示:
-
如果滚动是轴锁定的,则在滚动期间应忽略另一个轴上的任何吸附位置。(然而,另一个轴上的吸附位置仍可能影响最终的滚动位置。)
-
为了防止远处的屏幕外元素对滚动位置产生难以理解的影响,如果吸附位置的元素距离吸附口在可滚动溢出区域中移动时定义的“走廊”太远,或者距离仅具有预期方向的滚动走廊太远,或者距离仅具有预期终点位置的滚动后的吸附口太远,则应忽略它们。
-
用户代理必须确保用户无论使用哪种滚动方法都可以“逃离”吸附位置。例如,如果吸附类型为 mandatory 且下一个吸附位置距离超过两个屏幕宽度,那么简单的“始终吸附到最近”选择算法可能会在用户的终点位置仅为一个屏幕宽度时“困住”用户。相反,一种更智能的算法,即仅在终点与起始吸附位置距离很小的情况下返回,否则忽略起始吸附位置,将提供更好的行为。
-
如果页面导航到一个定义了目标元素的片段(例如,可以被 :target 匹配,或者是
scrollIntoView()的目标),并且该元素定义了一些吸附位置,则如果其最近的滚动容器是一个滚动吸附容器,用户代理必须吸附到该元素的一个吸附位置。用户代理可以甚至在滚动容器具有 scroll-snap-type: none 时也这样做。
附录 A:完整属性
物理和逻辑完整属性(及其简写)的交互方式定义见 [CSS-LOGICAL-1]。
scroll-padding 的物理完整属性
| 名称 | scroll-padding-top, scroll-padding-right, scroll-padding-bottom, scroll-padding-left |
|---|---|
| 值 | auto | <length-percentage> |
| 初始值 | auto |
| 应用于 | 滚动容器 |
| 可继承 | 否 |
| 百分比 | 相对于滚动容器滚动口 |
| 计算值 | 关键字 auto 或计算出的 <length-percentage> 值 |
| 规范顺序 | 按语法 |
| 动画类型 | 按计算值类型 |
scroll-padding 的这些完整属性分别指定吸附口的顶部、右侧、底部和左侧边缘。负值无效。
scroll-padding 的流相关完整属性
| 名称 | scroll-padding-inline-start, scroll-padding-block-start, scroll-padding-inline-end, scroll-padding-block-end |
|---|---|
| 值 | auto | <length-percentage> |
| 初始值 | auto |
| 应用于 | 滚动容器 |
| 可继承 | 否 |
| 百分比 | 相对于滚动容器滚动口 |
| 计算值 | 关键字 auto 或计算出的 <length-percentage> 值 |
| 规范顺序 | 按语法 |
| 动画类型 | 按计算值类型 |
scroll-padding 的这些完整属性分别指定吸附口的块起点、内联起点、块终点和内联终点边缘。负值无效。
| 名称 | scroll-padding-block, scroll-padding-inline |
|---|---|
| 值 | [ auto | <length-percentage> ]{1,2} |
| 初始值 | auto |
| 应用于 | 滚动容器 |
| 可继承 | 否 |
| 百分比 | 相对于滚动容器滚动口 |
| 计算值 | 见各个属性 |
| 动画类型 | 按计算值 |
| 规范顺序 | 按语法 |
scroll-padding-block-start + scroll-padding-block-end 和 scroll-padding-inline-start + scroll-padding-inline-end 的这些简写属性是 scroll-padding 的完整属性,并分别指定吸附口的块轴和内联轴边缘。
如果指定了两个值,第一个值给出起点值,第二个值给出终点值。
scroll-margin 的物理完整属性
| 名称 | scroll-margin-top, scroll-margin-right, scroll-margin-bottom, scroll-margin-left |
|---|---|
| 值 | <length>(长度) |
| 初始值 | 0 |
| 应用于 | 所有元素 |
| 可继承 | 否 |
| 百分比 | 不可用 |
| 计算值 | 绝对长度 |
| 规范顺序 | 按语法 |
| 动画类型 | 按计算值类型 |
scroll-margin 的这些完整属性分别指定滚动吸附区域的顶部、右侧、底部和左侧边缘。
scroll-margin 的流相关完整属性
| 名称 | scroll-margin-block-start, scroll-margin-inline-start, scroll-margin-block-end, scroll-margin-inline-end |
|---|---|
| 值 | <length>(长度) |
| 初始值 | 0 |
| 应用于 | 所有元素 |
| 可继承 | 否 |
| 百分比 | 不可用 |
| 计算值 | 绝对长度 |
| 规范顺序 | 按语法 |
| 动画类型 | 按计算值类型 |
scroll-margin 的这些完整属性分别指定滚动吸附区域的块起点、内联起点、块终点和内联终点边缘。
| 名称 | scroll-margin-block, scroll-margin-inline |
|---|---|
| 值 | <length>{1,2} |
| 初始值 | 0 |
| 应用于 | 所有元素 |
| 可继承 | 否 |
| 百分比 | 不可用 |
| 计算值 | 见各个属性 |
| 动画类型 | 按计算值类型 |
| 规范顺序 | 按语法 |
scroll-margin-block-start + scroll-margin-block-end 和 scroll-margin-inline-start + scroll-margin-inline-end 的这些简写属性是 scroll-margin 的完整属性,并分别指定滚动吸附区域的块轴和内联轴边缘。
如果指定了两个值,第一个值给出起点值,第二个值给出终点值。
7. 隐私与安全考虑
本规范未公开任何未直接向 DOM 公开的信息;它只是使滚动功能稍微强大了一些。没有任何新的隐私或安全考虑。
8. 致谢
非常感谢 David Baron、Simon Fraser、Håkon Wium Lie、Theresa O’Connor、François Remy、Majid Valpour,特别是 Robert O’Callahan 提出的建议和推荐,这些已合并到本文档中。
9. 变更记录
9.1. 自 2019 年 3 月 19 日 CR 以来的变更
自 2019 年 3 月 19 日候选推荐标准以来的变更包括:
- 指定了用于解析 scroll-snap-align 的书写模式。(Issue 3815)
-
定义了多个元素重合时重新吸附的要求。(Issue 4651)
如果滚动容器在内容更改前已吸附,且该相同的吸附位置仍然存在(例如其关联元素未被删除),则内容更改后,滚动容器必须重新吸附到该相同的吸附位置。如果多个盒子在之前已吸附且它们的吸附位置不再重合,则如果其中一个已获得焦点或成为目标,滚动容器必须重新吸附到该盒子;否则,重新吸附到哪一个由 UA 定义。(例如,随着布局的移动导致其他元素的吸附位置对齐和失对齐,UA 可以跟踪当前吸附的元素。)
-
要求重新吸附到新元素时动画表现得与其他任何“滚动进入视图”操作一样。(Issue 4609)
由于重新吸附操作而导致的向新盒子或不同盒子的滚动,必须表现和动画化得与其他任何“滚动进入视图”操作一样,包括遵循 scroll-behavior 等控件。然而,重新吸附到与之前相同的盒子的滚动行为由 UA 定义。例如,当吸附到某个部分的开始处时,如果文档较早部分动态添加了内容,UA 可能选择不对滚动到该部分新位置的过程进行动画处理,以营造没有滚动的错觉。
-
明确定义了 scroll-snap-type 和 scroll-padding 值按预期从根元素传播到文档视口。(Issue 3740)
用户代理必须将根元素上设置的 scroll-snap-type 值应用于文档视口。注意,与 overflow 不同,scroll-snap-type 值不会从 HTML
body传播。用户代理必须将根元素上设置的 scroll-padding 值应用于文档视口。(注意,与 overflow 不同,scroll-padding 值不会从 HTML
body传播。) -
澄清了虽然吸附对齐是相对于视觉视口的,但 scroll-padding 是相对于布局视口解析的,以便在根视口上 scroll-padding 和 inset 保持一致。(Issue 4393)
定义从滚动口相应边缘向内的偏移量。当应用于根视口时,该偏移量的计算和应用相对于布局视口(而非视觉视口),方式与固定定位盒子上的相应插入属性相同;最佳观看区域是与视觉视口相交的剩余区域。
- 更正了 scroll-padding-inline 和 scroll-padding-block 的“适用于(Applies to)”行。(Issue 5845)
提供了评论处理说明(Disposition of Comments)。
9.2. 自 2019 年 1 月 31 日 CR 以来的变更
自 2019 年 1 月 31 日候选推荐标准以来的变更包括:
-
强调了即使在滚动吸附功能关闭时,scroll-padding 和 scroll-margin 仍然适用。(Issue 3721)
此外,为了在关闭吸附功能时也能提供更好的分页和滚动定位控制,本模块为所有滚动容器定义了 scroll-padding 属性,用于调整滚动容器的最佳观看区域,以实现分页和滚动进入视图的操作;同样,scroll-margin 属性可用于任何盒子,以调整其视觉区域,用于滚动进入视图的操作。
如果页面导航至定义了目标元素(即会被 :target 匹配,或作为
scrollIntoView()的目标)的片段,用户代理应使用该元素的 滚动捕捉区域,而不是仅仅使用其边界框,来确定 可滚动溢出区域 的哪个部分应进入视图,即使在该元素上关闭了捕捉或未应用捕捉时也是如此。
9.3. 自 2018 年 8 月 14 日候选推荐标准(CR)以来的变更
自 2018 年 8 月 14 日候选推荐标准以来的变更包括:
- 更正了 scroll-padding 的普通属性(longhands),使其在属性定义表中列出了新的 auto 关键字。(问题 3189)
- 修复了属性定义表中的“计算值(Computed value)”和“动画类型(Animation type)”行。
- 清理了 scroll-margin 属性定义表中冗余的 <percentage> 值。(问题 3289)
现提供一份 意见处理记录。
9.4. 自 2017 年 12 月 14 日候选推荐标准(CR)以来的变更
自 2017 年 12 月 14 日候选推荐标准以来的变更包括:
- 修复了 scroll-snap-align 简写属性,按照逻辑简写惯例,改为先赋值块轴(block-axis)值,再赋值内联轴(inline-axis)值。(问题 2232)
- 将 auto 关键字添加为 'scroll-padding' 的初始值,以考虑用户代理启发式规则。(问题 2728)
-
在 scroll-snap-type 的定义中明确了诸如
scrollTo()等编程滚动操作同样受捕捉影响。(问题 2593)在相关的 滚动容器 上使用 scroll-snap-type 属性,作者可以要求滚动视口在滚动操作后落在特定的 捕捉位置 上(包括诸如
scrollTo()方法等编程滚动)。 - 调整了 § 5.2.1 将有效的捕捉位置限定在可见框范围内 中的措辞,使其较 旧版本 更为清晰。(问题 2526)
现提供一份 意见处理记录。
9.5. 自 2017 年 8 月 24 日候选推荐标准(CR)以来的变更
自 2017 年 8 月 24 日候选推荐标准以来的变更包括:
-
:target/
scrollIntoView()等操作应考虑 scroll-margin,无论是否开启捕捉。(问题 1)如果页面导航至定义了目标元素(即会被 :target 匹配,或作为
scrollIntoView()的目标)的片段,用户代理应使用该元素的 滚动捕捉区域,而不是仅仅使用其边界框,来确定 可滚动溢出区域 的哪个部分应进入视图。 -
:target/
scrollIntoView()等操作在开启捕捉时必须(而非应该)使用捕捉位置。(问题 1)如果页面导航至定义了目标元素的片段,且该元素定义了某些 捕捉位置,则用户代理
应该必须 捕捉 到该元素的其中一个 捕捉位置(如果其最近的 滚动容器 是一个 滚动捕捉容器)。即使在 滚动容器 设置为 scroll-snap-type: none 时,用户代理也可以这样做。 - 将 scroll-snap-margin 重命名为 scroll-margin,以反映其在提供滚动到元素的缓冲空间方面更通用的作用,与捕捉行为无关。(问题 4)
现提供一份 意见处理记录。
9.6. 自 2016 年 10 月 20 日候选推荐标准(CR)以来的变更
自 2016 年 10 月 20 日候选推荐标准以来的变更包括:
- 将 scroll-padding 限制为非负值。(问题 1084)
值必须是非负的,且其解释方式与 padding 相同……
- 在 § 6.1 滚动方法类型 的示例中添加了分页和归位操作。(问题 1605)
- 明确了在一个轴上的捕捉可能会影响在该轴的另一方向是否可能捕捉到特定的捕捉区域。(问题 950)
尽管 scroll-snap-type: both 在每个轴上独立评估 捕捉位置,但一个轴上 捕捉位置 的 选择 可能会受到另一个轴上 捕捉位置 的影响。例如,在一个轴上的捕捉可能会将另一个轴本应与其对齐的 捕捉区域 移出屏幕,使其 捕捉位置 无效,从而不可选择。
- 明确了 scroll-padding 和 scroll-margin 简写属性如何为其普通属性赋值。(问题 1050)
- 明确了滚动捕捉不强制要求任何特定的输入方法。(问题 1305)
本规范仅适用于用户代理支持的滚动方法;它不要求用户代理支持任何特定的输入或滚动方法。
- 明确了 scroll-snap-stop 对各种滚动操作的预期影响。(问题 1552)
- 明确了 scroll-snap-stop 应用于元素定义的 捕捉位置,而不应用于 滚动捕捉容器 中的所有 捕捉位置。
- 修复了示例中的一些语法错误,并在 scroll-snap-type 部分添加了一个新示例。(问题 827)
现提供一份 意见处理记录。