CSS滚动捕捉模块第1级

W3C候选推荐快照,

此版本:
https://www.w3.org/TR/2021/CR-css-scroll-snap-1-20210311/
最新发布版本:
https://www.w3.org/TR/css-scroll-snap-1/
编辑草稿:
https://drafts.csswg.org/css-scroll-snap-1/
之前版本:
实施报告:
https://wpt.fyi/results/css/css-scroll-snap
测试套件:
http://test.csswg.org/suites/css-scroll-snap-1_dev/nightly-unstable/
问题追踪:
CSSWG问题库
编辑:
Matt Rakow (微软)
Jacob Rossi (微软)
Tab Atkins-Bittner (谷歌)
Elika J. Etemad / fantasai (邀请专家)
为此规范建议编辑:
GitHub 编辑器

摘要

此模块包含用于控制“快照位置”的平移和滚动行为的特性。

CSS 是一种描述结构化文档(如 HTML 和 XML)在屏幕、纸张等上的呈现的语言。

本文件的状态

本节描述了该文件在发布时的状态。其他文档可能会取代此文档。当前 W3C 出版物列表和最新修订版本的技术报告可在 W3C 技术报告索引 中找到。

本文件由 CSS 工作组 发布为 候选推荐快照。发布为候选推荐并不意味着 W3C 会员的认可。候选推荐快照已接受 广泛审查,并旨在收集实施经验。该文档旨在成为 W3C 推荐;它将至少保持候选推荐状态,直到 以收集更多反馈。

请通过 在 GitHub 上提交问题(首选)发送反馈,包括在标题中使用规范代码“css-scroll-snap”,例如:“[css-scroll-snap] …评论摘要…”。所有问题和评论均被 存档。另外,反馈可以发送至(存档)公共邮件列表 www-style@w3.org。

本文件受 2020 年 9 月 15 日 W3C 过程文档 管辖。

本文件由一个在 W3C 专利政策 下运作的小组制作。W3C 保持一份 任何专利披露的公开列表,该列表与小组的交付物相关;该页面还包括披露专利的说明。对自己所知的专利,如认为包含 基本权利要求,的个人必须根据 W3C 专利政策第 6 节 披露信息。

在 CR 期间将生成测试套件和实施报告。

以下特性处于风险中,可能在 CR 期间被删除:

“处于风险中”是 W3C 过程中的专业术语,并不一定意味着该特性有被删除或延迟的危险。它表示工作组认为该特性可能难以在及时的情况下进行可互操作的实现,并将其标记为此使得工作组在过渡到提议推荐阶段时可以在必要时删除该特性,而无需先发布不带该特性的新的候选推荐。

1. 引言

本节不是规范性内容。

流行的用户体验范式在可滚动内容中通常采用分页或逻辑分区。 这在触摸交互中尤为明显, 用户通过平铺排列的内容快速滑动要比通过点按导航深入层级结构要更快、更容易。 例如,用户通过照片幻灯片视图快速浏览照片专辑中的多张照片 要比逐个点击专辑中的照片更方便。

然而,由于触摸滑动和鼠标滚轮滚动等滚动输入的不精确特性, 网页开发者很难保证良好的滚动体验, 尤其是创造分页效果。 例如,用户可能会落在一个不合适的滚动位置, 使得某个项目部分出现在屏幕上。

为此,本模块引入了滚动捕捉位置,用于强制规定滚动容器的滚动视口在滚动操作完成后可以结束的滚动位置。

此外,为了在捕捉关闭时提供更好的分页和滚动位置控制, 本模块定义了滚动内边距属性 用于所有滚动容器, 以调整滚动容器的最佳查看区域, 以便进行分页和滚动到视图操作。 类似地,滚动外边距属性可以用于任何盒子 以调整其可视区域, 用于滚动到视图操作。

1.1. 模块交互

本模块扩展了[CSS2]第11.1节中定义的滚动用户界面功能。

本模块中的属性不适用于::first-line和::first-letter伪元素。

1.2. 值定义

本规范遵循CSS属性定义约定, 来自[CSS2],使用值定义语法来自[CSS-VALUES-3]。 本规范未定义的值类型在CSS值和单位[CSS-VALUES-3]中定义。 与其他CSS模块的组合可能扩展这些值类型的定义。

除了在定义中列出的属性特定值, 本规范定义的所有属性 还接受CSS全局关键字作为属性值。 为了可读性,这些未被明确重复。

2. 激励示例

在此示例中,一系列排列在滚动容器中的图像被用来构建照片画廊。在此示例中 滚动容器大于包含的照片 (以便可以同时看到多张图像),而且图像 尺寸各异。使用强制的基于元素的捕捉 位置,滚动将始终以图像居中在滚动容器的滚动视口结束。
img {
    /* 指定每张照片的中心应与滚动的中心对齐 */
    scroll-snap-align: none center;
}
.photoGallery {
    width:500px;
    overflow-x: auto;
    overflow-y: hidden;
    white-space: nowrap;
    /* 要求在滚动操作完成时滚动位置始终处于捕捉位置。 */
    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>
示例中滚动容器内容的布局。 捕捉视口由红色矩形表示,捕捉区域由黄色 矩形表示。由于滚动捕捉对齐在横向轴上为“中心”, 每个滚动位置都会建立一个捕捉位置,将捕捉视口的X中心 (由红色虚线表示)与捕捉区域的X中心 (由黄色虚线表示)对齐。
此示例构建了一个分页文档,使每个 页面靠近(但不完全在)滚动 容器的边缘。 这使得前一页可以“窥视”上方,以使用户意识到他们尚未 到达文档顶部。 使用临近捕捉位置而不是强制捕捉位置允许用户在 页面中途停止(而不是强迫他们 一次捕捉一页)。然而,如果滚动操作将在捕捉位置附近完成,则滚动将被调整以 对齐页面,如所指定。
.page {
    /* 将每个页面的顶部定义为应用于捕捉的边缘 */
    scroll-snap-align: start none;
}
.docScroller {
    width:500px;
    overflow-x: hidden;
    overflow-y: auto;
    /* 指定每个元素的捕捉区域应与顶部边缘偏移100px对齐。 */
    scroll-padding: 100px 0 0;
    /* 鼓励在滚动操作完成时以捕捉位置结束,如果它接近捕捉位置 */
    scroll-snap-type: y proximity;
}
<div class="docScroller">
    <div class="page">
    第 1 页</div>
    <div class="page">
    第 2 页</div>
    <div class="page">
    第 3 页</div>
    <div class="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
适用对象: 所有元素
继承: 否
百分比: 不适用
计算值: 指定关键字
规范顺序: 按语法
动画类型: 离散

scroll-snap-type 属性指定 滚动容器是否为滚动捕捉容器、 它进行捕捉的严格程度, 以及考虑哪些轴。 如果未指定严格度值,则假定为 proximity。

在此示例中,在块轴(水平书写的y轴,垂直书写的x轴)上启用对标题的捕捉:
html {
  scroll-snap-type: block;   /* 应用于主文档滚动器 */
}
h1, h2, h3, h4, h5, h6 {
  scroll-snap-align: start;  /* 捕捉到视口的开始(顶部) */
}

用户代理必须将根元素上设置的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
如果在滚动容器上指定, 则该滚动容器不得进行捕捉。
mandatory
如果在滚动容器上指定, 则当没有正在进行的滚动操作时,该滚动容器必须捕捉到某个捕捉位置。 如果存在有效的捕捉 位置, 则滚动容器必须在滚动 结束时捕捉 (如果不存在,则不会发生捕捉)。
proximity
如果在滚动容器上指定, 则该滚动容器可以在滚动结束时捕捉到某个捕捉位置, 具体由 UA 根据滚动参数自行决定。

作者使用强制捕捉位置时,应考虑 不同尺寸的屏幕以及(如适用)不同尺寸的内容。 特别是,尽管 UA 会处理对大于滚动口的已捕捉元素的访问, 但如果作者为不相邻的同级元素指定强制捕捉, 当中间内容比屏幕更长时, 这些内容可能会变得无法访问。

如果一个框是滚动 容器,或者其 scroll-snap-type 的值不是 none,则该框会捕获捕捉 位置。 如果一个框的包含块链上最近的、捕获捕捉位置的祖先是一个 滚动容器,且其 scroll-snap-type 值不是 none, 则该祖先就是此框的滚动捕捉容器。 否则,该框没有滚动捕捉容器, 并且其捕捉 位置不会触发捕捉。

4.1.3. 布局变化后的重新捕捉

如果文档的内容或布局发生变化 (例如,内容被添加、移动、删除、调整大小), 使得 snapport 的内容发生变化, 用户代理必须重新评估结果的 滚动位置, 如有需要则重新捕捉。 如果 滚动容器 在内容变化前已被 捕捉 并且相同的 捕捉位置 仍然存在 (例如,其关联元素未被删除), 则在内容变化后,滚动容器必须重新捕捉到该位置。 如果多个框在之前被 捕捉, 而它们的 捕捉位置 不再重合, 则如果其中一个获得焦点或被选中, 则 滚动容器 必须重新捕捉到该框, 否则重新捕捉到哪个则由用户代理定义。 (用户代理可以例如跟踪被捕捉的元素, 随着布局的变化而调整其他元素的 捕捉位置。)

重新捕捉到新的或不同框的滚动操作 必须像任何其他滚动到视图操作一样表现和动画, 包括遵循如 scroll-behavior 这样的控制。 然而,重新捕捉到之前相同框的滚动行为是由用户代理定义的。 用户代理可以例如,当捕捉到某个部分的开始时, 选择不将滚动动画到该部分的新位置, 因为内容在文档的早期动态添加,以创建不滚动的错觉。

在以下示例中, 日志控制台, 当初始加载及每条消息添加到底部时, 将保持捕捉到底部内容, 除非用户已滚动远离该边缘:
.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 可以使用启发式规则检测非零值更为合适的情况。

例如, UA 可以检测 position:fixed 元素何时 被用作不透明且不可滚动的“页眉”, 遮挡其下方的内容, 并将顶部偏移量解析为该元素的高度, 使“向下翻页”操作(例如按下 PgDn) 自动滚动一个“可见页面”的内容。

这些偏移量会缩小滚动口中 对于滚动操作而言被视为“可查看”的区域: 它们不会影响布局, 不会影响滚动原点或初始位置, 也不会影响元素是否被视为实际可见, 但应 影响元素或插入符是否被视为已滚动到视野内 (例如对于定向或聚焦操作), 并减少翻页操作的滚动量 (例如使用 PgUp 和 PgDn 键, 或从滚动条触发等效操作), 以便用户在滚动口的最佳查看区域内看到连续的内容流。

对于滚动捕捉 容器,此区域还定义了 滚动捕捉口——计算捕捉 位置时,滚动口中用作对齐容器以对齐滚动捕捉区域的区域。

在这个例子中,scroll-padding 被用来在未被固定位置工具栏遮挡的滚动端口部分中居中幻灯片图像。
html {
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    scroll-padding: 0 500px 0 0;
}
.toolbar {
    position: fixed;
    height: 100%;
    width: 500px;
    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()的目标), 用户代理应使用该元素的滚动捕捉区域, 而不仅仅是其边框盒子, 来确定将哪些区域带入视图可滚动溢出区域, 即使捕捉已关闭或未在此元素上应用。

5.2. 滚动快照对齐:scroll-snap-align 属性

名称: scroll-snap-align
值: [ none | start | end | center ]{1,2}
初始: none
适用对象: 所有元素
继承: 否
百分比: 不适用
计算值: 两个关键字
规范顺序: 按语法
动画类型: 离散

scroll-snap-align 属性指定 盒子的捕捉 位置作为其捕捉区域 (作为对齐主题)在其捕捉容器的捕捉端口(作为对齐容器)中的对齐。 两个值分别指定在块轴和行内轴中的 捕捉对齐,具体由捕捉容器的书写模式决定。 如果只指定一个值,则第二个值默认为相同值。

值定义如下:

none
此盒子在指定轴中不定义捕捉位置。
start
此盒子的滚动捕捉区域在滚动 容器的捕捉端口中的起始对齐为在指定轴上的捕捉位置。
end
此盒子的滚动捕捉区域在滚动 容器的捕捉端口中的结束对齐为在指定轴上的捕捉位置。
center
此盒子的滚动捕捉区域在滚动 容器的捕捉端口中的中心对齐为在指定轴上的捕捉位置。

起始和结束对齐相对于捕捉容器的书写模式解析,除非滚动捕捉区域大于捕捉口, 在这种情况下,它们相对于 框自身的书写模式解析。 (这通常可使容器中的项目具有一致的捕捉对齐, 同时确保 start 始终对齐项目, 以便从头开始阅读其内容。)

5.2.1. 限定有效捕捉位置到可见盒子

由于滚动捕捉的目的是在滚动区内对齐内容以获得最佳观看效果, 如果捕捉位置的滚动位置被认为有效,则捕捉到它将使贡献的捕捉区域完全位于捕捉端口之外,即使它满足所需的对齐, 捕捉区域也不算有效。

例如,如果一个捕捉区域的顶部边缘 与捕捉口的顶部边缘重合, 则该捕捉区域与捕捉口顶部对齐; 并且,如果该捕捉区域至少有一部分位于屏幕上, 这会被视为该捕捉区域进行块轴起始对齐捕捉时的有效捕捉位置。 然而,如果整个捕捉区域都位于捕捉口之外, 那么该滚动容器就不能被视为已捕捉,因为所需的对齐虽然 已得到满足,却与查看者无关。
╔════viewport════╗┈┈┈┈┈┈┈┈┌──────────────┐
║  ┌─────┐ ┌──┐  ║        │ 顶部捕捉 │
║  ├──┐  │ └──┘  ║        │   元素    │
║  └──┴──┘       ║        │              │
╚════════════════╝        │              │
                          └──────────────┘
屏幕外元素的对齐不算作捕捉。
为什么仅在元素可见时限制捕捉? 正如WebKit实现者指出的, 将捕捉边缘无限延伸跨越画布只允许对齐网格布局,并且在屏幕外元素未对齐屏幕内元素时, 会产生奇怪的用户体验。 (如果这一要求对实现者来说过于苛刻,我们可以默认采用网格行为,并稍后引入开关以实现更智能的行为。)

注:尽管 scroll-snap-type: both 会分别在各轴上评估捕捉 位置,但一个轴上捕捉位置的选择 可能会受到另一轴上捕捉位置的影响。 例如,一个轴上的捕捉 可能会将在另一轴上本应对齐的捕捉区域推到屏幕之外, 从而使其捕捉位置无效,因而 无法选择。

5.2.2. 捕捉超出滚动端口的盒子

如果捕捉区域 在某个轴上的大小大于捕捉端口, 则在该轴上,任何使捕捉区域覆盖 捕捉端口的滚动位置, 以及几何上前后的捕捉位置之间的距离 大于该轴上捕捉端口的大小, 都是该轴上的有效捕捉位置。 用户代理可以将指定的对齐用作某些滚动操作(例如显式分页)的更精确目标。

例如,取§ 2 动机示例中的第一个示例,该示例中有一张照片作为区域。 作者希望强制从一个项目捕捉到另一个项目, 但如果该项目恰好比视口大, 你希望能够在你越过它后滚动查看整个内容。

由于捕捉区域 大于捕捉端口, 当该区域完全填充视口时, 容器可以任意滚动 并不会试图捕捉回其对齐位置。 然而,如果容器滚动到使该区域在某个轴上不再完全填充视口, 该区域会抵抗外部滚动, 直到它滚动到足以触发捕捉到不同的捕捉位置。

另一个例子是, 嵌套的section 元素上的强制顶部捕捉 可以产生大的捕捉区域(来自大的顶层部分), 可能填充着较小的捕捉区域(来自子部分)。 当子部分足够小的时候, 它们正常捕捉; 当它们较长时, 观众可以在其中任意滚动, 或在没有子部分可捕捉的大的顶层部分中滚动。
┌─ 顶层部分 ─┐ ━┓
│                     │ 1┃
│                     │  ┃
│                     │ ━┩
│                     │  ┆
│                     │  ┆
│┌─── 子部分       ───┐│  ╯ ━┓
│└───────────────────┘│    2┃
│┌─── 子部分       ───┐│ ━┓  ┃
││                   ││ 3┃ ━┛
│└───────────────────┘│  ┃
│┌─── 子部分       ───┐│ ━┛ ━┓
│└───────────────────┘│    4┃
│┌─── 子部分       ───┐│ ━┓  ┃
││                   ││ 5┃ ━┛
││                   ││  ┃
││                   ││ ━┩
││                   ││  ┆
││                   ││  ┆
││                   ││  ┆
│└───────────────────┘│  ┆
└─────────────────────┘  ╯
在上面的图中, 五个编号视口 代表与顶层部分及其四个子部分关联的五个捕捉位置。 因为第一个和最后一个捕捉位置属于高于视口的范围, 所以允许观众在每个范围的顶部和底部之间自由滚动。

注意: 如果作者改为在每个部分的标题上设置强制捕捉位置, (而不是部分本身), 则第一个和第五个部分的内容将对用户部分不可访问, 因为标题捕捉区域并未扩展到覆盖整个部分。 这就是为什么在可能间隔较远的元素上使用强制捕捉位置是个坏主意。

5.2.3. 无法到达的快照位置

如果指定的捕捉 位置不可达, 即要与其对齐,就需要将滚动 容器的视口 滚动到其可滚动溢出区域的边缘之外, 则此捕捉区域的使用捕捉位置是 在每个相关轴上朝所需捕捉位置 尽可能多地滚动后得到的位置。

5.3. 滚动快照限制:scroll-snap-stop 属性

名称: scroll-snap-stop
值: normal | always
初始值: normal
适用于: 所有元素
继承: 否
百分比: 不适用
计算值: 指定的关键字
规范顺序: 按语法
动画类型: 离散

在有意的滚动方向上, 滚动容器可以“越过”几个可能的快照位置 (如果滚动操作以相同的方向但较小的距离进行, 这些位置都是有效的快照位置), 然后到达滚动操作的自然终点并选择其最终的滚动位置。 scroll-snap-stop属性允许这样的可能快照位置“捕捉”滚动操作, 强制滚动容器在滚动操作自然结束之前停止。

值的定义如下:

normal
在执行滚动操作时, 滚动容器可以越过由该元素定义的快照位置。
always
在执行滚动操作时, 滚动容器必须不越过由该元素定义的快照位置; 它必须立即快照到该元素的第一个快照位置。

该属性对只有预期结束位置的滚动操作没有影响, 因为它们在概念上不会“越过”任何快照位置。

6. 捕捉机制

选择要捕捉到的捕捉位置的精确模型算法故意保持大部分未定义, 以便用户代理可以考虑复杂的用户意图和交互模型, 并随着时间的推移调整其响应方式, 以最佳方式服务用户。

本节定义了一些有用的概念,以帮助讨论滚动捕捉机制,并提供了有效滚动捕捉策略可能是什么样的指南。 鼓励用户代理适应这些指导,并在定义自己的捕捉行为时应用自己的最佳判断。 它还提供了一小部分行为要求,以确保作者在设计其接口时可以依赖的最低合理行为,以考虑滚动捕捉。

6.1. 滚动方法类型

当页面被滚动时,该动作是通过意图结束位置和/或意图方向来执行的。 这两者的每种组合定义了一种独特的滚动类别,可以稍微以不同的方式对待:

意图结束 位置
只有意图结束位置的滚动的常见示例包括:
  • 没有动量释放的平移手势

  • 显式操控滚动条“滑块”

  • 通过API编程滚动,如scrollTo()

  • 在文档的可聚焦元素之间切换

  • 导航到页面内的锚点

  • 诸如Home/End键的归位操作

意图方向和结束位置
具有意图方向和结束位置的滚动的常见示例包括:
  • 被解释为具有动量的“抛掷”手势

  • 通过API编程滚动,如scrollBy()

  • 分页操作,如PgUp/PgDn键(或在滚动条上的等效操作)

在介入捕捉点等特性之前,滚动的意图终点是其自然终点。

意图 方向
只有意图方向的滚动的常见示例包括:
  • 按下键盘上的箭头键(或在滚动条上的等效操作)

  • 被解释为固定(而非惯性)滚动的滑动手势

此外,由于页面布局通常垂直和/或水平对齐事物,用户代理有时会在其方向足够垂直或水平时对滚动进行轴锁定。 轴锁定的滚动仅绑定在该轴上滚动。 这防止了精度较低的输入机制在非主要轴上漂移。

注意:本规范仅适用于用户代理支持的滚动方法; 它不要求用户代理支持任何特定的输入或滚动方法。

6.2. 选择快照位置

一个滚动容器的整个可滚动溢出区域中可以散布许多捕捉区域。 选择捕捉位置的简单算法可能产生用户难以凭直觉理解的 行为, 因此在设计选择算法时需要谨慎。 以下是一些有助于选择过程的建议:

附录 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日候选推荐以来的变更

自2019年3月19日候选推荐以来的变更包括:

已提供意见处理说明。

9.2. 自2019年1月31日候选推荐以来的变更

自2019年1月31日候选推荐以来的变更包括:

9.3. 自2018年8月14日候选推荐以来的变更

自2018年8月14日候选推荐以来的变更包括:

提供了意见处理说明。

9.4. 自2017年12月14日候选推荐以来的变更

自 2017 年 12 月 14 日 候选推荐标准以来的变更包括:

已有意见处理情况 可供查阅。

9.5. 自2017年8月24日候选推荐以来的变更

自2017年8月24日候选推荐以来的变更包括:

提供了意见处理说明。

9.6. 自2016年10月20日候选推荐以来的变更

自2016年10月20日候选推荐以来的变更包括:

提供了意见处理说明。

规范一致性

文档约定

一致性要求通过描述性断言和RFC 2119术语的结合来表达。关键字“MUST(必须)”,“MUST NOT(不得)”,“REQUIRED(需要)”,“SHALL(应)”,“SHALL NOT(不得)”,“SHOULD(应该)”,“SHOULD NOT(不应该)”,“RECOMMENDED(推荐)”,“MAY(可以)”和“OPTIONAL(可选的)”在本文件的规范部分应按照RFC 2119的描述进行解释。 但是,为了可读性,这些词语在本规范中不会以全大写字母形式出现。

本规范的所有文本都是规范性的,除非明确标记为非规范部分、示例和注释。[RFC2119]

本规范中的示例以“例如”开头,或通过class="example"从规范文本中分隔出来,例如:

这是一个说明性的示例。

信息性注释以“注释”一词开头,并通过class="note"从规范文本中分隔出来,例如:

注释:这是一个信息性注释。

建议性部分是规范性部分,旨在引起特别注意,并使用<strong class="advisement">进行强调,例如:用户代理(UAs)必须提供可访问的替代方案。

一致性类别

本规范的一致性定义了三个一致性类别:

样式表
CSS 样式表。
渲染器
用户代理(UA),用于解释样式表的语义并渲染 使用它们的文档。
创作工具
用户代理(UA),用于编写样式表。

样式表如果使用本模块中定义的语法的所有声明都是有效的,并且符合通用CSS语法和本模块中每个特性的各自语法,则符合本规范。

渲染器如果除了按照相关规范解释样式表之外,还正确支持本规范定义的所有功能,解析并正确渲染文档,则符合本规范。 但是,由于设备限制,用户代理无法正确渲染文档并不使该用户代理不符合规范。(例如,用户代理不需要在单色监视器上渲染颜色。)

创作工具如果编写的样式表在语法上符合通用CSS语法和本模块中每个特性的语法,并且符合本模块描述的样式表的所有其他一致性要求,则符合本规范。

部分实现

为了让作者能够利用前向兼容的解析规则分配回退值,CSS渲染器必须将任何无用的规则、属性、属性值、关键字和其他语法结构视为无效,并根据需要忽略。特别是,用户代理不得选择性地忽略无效的组件值并在单个多值属性声明中使用支持的值:如果任何值被视为无效(因为不支持的值必须被视为无效),CSS要求整个声明被忽略。

不稳定和专有功能的实现

为了避免与未来稳定的CSS功能发生冲突,CSS工作组建议遵循最佳实践,以实现不稳定的功能和专有扩展的CSS。

非实验性实现

一旦规范达到候选推荐阶段,非实验性实现是可能的,且实现者应发布无前缀的任何CR级别功能的实现,只要他们能够证明其已根据规范正确实现。

为了建立和维护CSS在各个实现之间的互操作性,CSS工作组要求非实验性CSS渲染器在发布任何CSS功能的无前缀实现之前,向W3C提交实现报告(如果必要,还应提交用于该实现报告的测试用例)。提交给W3C的测试用例需经CSS工作组审查和修正。

有关提交测试用例和实现报告的更多信息,可以在CSS工作组网站http://www.w3.org/Style/CSS/Test/上找到。问题应通过邮件public-css-testsuite@w3.org提出。

CR退出标准

为了将本规范推进到提议推荐阶段,每个功能必须有至少两个独立、互操作的实现。每个功能可以由不同的产品实现,不要求所有功能都由单个产品实现。根据此标准,我们定义以下术语:

独立
每个实现必须由不同的团队开发,且不得共享、重复使用或从其他合格实现中派生代码。不影响本规范实现的代码部分可豁免此要求。
互操作性
通过官方CSS测试套件中的相应测试用例,或对于非Web浏览器的实现,采用等效测试。每个相关测试应有相应的等效测试,如果此类用户代理(UA)用于声称互操作性。此外,如果此类UA用于声称互操作性,则必须有一个或多个额外的UA能够以相同方式通过这些等效测试,以实现互操作性。这些等效测试必须公开以供同行审查。
实现
一个用户代理,其:
  1. 实现了该规范。
  2. 向公众开放。该实现可以是正式发布的产品或其他公开的版本(例如,测试版、预览版或"夜间构建版")。非正式发布的产品版本必须在至少一个月的时间内实现该功能,以证明其稳定性。
  3. 非实验性(即该版本专为通过测试套件设计,且未来并不打算用于常规使用)。

本规范将保持候选推荐状态至少六个月。

索引

本规范定义的术语

通过引用定义的术语

参考文献

规范性引用

[CSS-ALIGN-3]
Elika Etemad; Tab Atkins Jr.. CSS Box Alignment Module Level 3. 2020年4月21日. WD. URL: https://www.w3.org/TR/css-align-3/
[CSS-BOX-4]
Elika Etemad. CSS Box Model Module Level 4. 2020年4月21日. WD. URL: https://www.w3.org/TR/css-box-4/
[CSS-CASCADE-5]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr.. CSS Cascading and Inheritance Level 5. 2021年1月19日. WD. URL: https://www.w3.org/TR/css-cascade-5/
[CSS-DISPLAY-3]
Tab Atkins Jr.; Elika Etemad. CSS Display Module Level 3. 2020年12月18日. CR. URL: https://www.w3.org/TR/css-display-3/
[CSS-LOGICAL-1]
Rossen Atanassov; Elika Etemad. CSS Logical Properties and Values Level 1. 2018年8月27日. WD. URL: https://www.w3.org/TR/css-logical-1/
[CSS-OVERFLOW-3]
David Baron; Elika Etemad; Florian Rivoal. CSS Overflow Module Level 3. 2020年6月3日. WD. URL: https://www.w3.org/TR/css-overflow-3/
[CSS-POSITION-3]
Elika Etemad; et al. CSS Positioned Layout Module Level 3. 2020年5月19日. WD. URL: https://www.w3.org/TR/css-position-3/
[CSS-PSEUDO-4]
Daniel Glazman; Elika Etemad; Alan Stearns. CSS Pseudo-Elements Module Level 4. 2020年12月31日. WD. URL: https://www.w3.org/TR/css-pseudo-4/
[CSS-VALUES-3]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 3. 2019年6月6日. CR. URL: https://www.w3.org/TR/css-values-3/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 4. 2020年11月11日. WD. URL: https://www.w3.org/TR/css-values-4/
[CSS-WRITING-MODES-4]
Elika Etemad; Koji Ishii. CSS Writing Modes Level 4. 2019年7月30日. CR. URL: https://www.w3.org/TR/css-writing-modes-4/
[CSS2]
Bert Bos; et al. 层叠样式表级别2修订版(CSS 2.1)规范. 2011年6月7日. REC. URL: https://www.w3.org/TR/CSS21/
[CSSOM-VIEW-1]
Simon Pieters. CSSOM View Module. 2016年3月17日. WD. URL: https://www.w3.org/TR/cssom-view-1/
[HTML]
Anne van Kesteren; et al. HTML 标准. 现行标准. URL: https://html.spec.whatwg.org/multipage/
[RFC2119]
S. Bradner. 在RFC中使用的关键字以表明要求级别. 1997年3月. 最佳当前实践. URL: https://tools.ietf.org/html/rfc2119
[SELECTORS-4]
Elika Etemad; Tab Atkins Jr.. 选择器第4级. 2018年11月21日. WD. URL: https://www.w3.org/TR/selectors-4/

属性索引

名称 值 初始值 应用于 继承 百分比 动画类型 规范顺序 计算值
scroll-margin <length>{1,4} 0 所有元素 否 不适用 按计算值类型 按语法 每边的绝对长度
scroll-margin-block <length>{1,2} 0 所有元素 否 不适用 按计算值类型 按语法 参见各个属性
scroll-margin-block-end <length> 0 所有元素 否 不适用 按计算值类型 按语法 绝对长度
scroll-margin-block-start <length> 0 所有元素 否 不适用 按计算值类型 按语法 绝对长度
scroll-margin-bottom <length> 0 所有元素 否 不适用 按计算值类型 按语法 绝对长度
scroll-margin-inline <length>{1,2} 0 所有元素 否 不适用 按计算值类型 按语法 参见各个属性
scroll-margin-inline-end <length> 0 所有元素 否 不适用 按计算值类型 按语法 绝对长度
scroll-margin-inline-start <length> 0 所有元素 否 不适用 按计算值类型 按语法 绝对长度
scroll-margin-left <length> 0 所有元素 否 不适用 按计算值类型 按语法 绝对长度
scroll-margin-right <length> 0 所有元素 否 不适用 按计算值类型 按语法 绝对长度
scroll-margin-top <length> 0 所有元素 否 不适用 按计算值类型 按语法 绝对长度
scroll-padding [ auto | <length-percentage> ]{1,4} auto 滚动容器 否 相对于滚动容器的滚动视口的对应维度 按计算值类型 按语法 每边的 auto 关键字或计算出的 <length-percentage> 值
scroll-padding-block [ auto | <length-percentage> ]{1,2} auto 滚动容器 否 相对于滚动容器的滚动视口 按计算值类型 按语法 参见各个属性
scroll-padding-block-end auto | <length-percentage> auto 滚动容器 否 相对于滚动容器的滚动视口 按计算值类型 按语法 auto 关键字或计算出的 <length-percentage> 值
scroll-padding-block-start auto | <length-percentage> auto 滚动容器 否 相对于滚动容器的滚动视口 按计算值类型 按语法 auto 关键字或计算出的 <length-percentage> 值
scroll-padding-bottom auto | <length-percentage> auto 滚动容器 否 相对于滚动容器的滚动视口 按计算值类型 按语法 auto 关键字或计算出的 <length-percentage> 值
scroll-padding-inline [ auto | <length-percentage> ]{1,2} auto 滚动容器 否 相对于滚动容器的滚动视口 按计算值类型 按语法 参见各个属性
scroll-padding-inline-end auto | <length-percentage> auto 滚动容器 否 相对于滚动容器的滚动视口 按计算值类型 按语法 auto 关键字或计算出的 <length-percentage> 值
scroll-padding-inline-start auto | <length-percentage> auto 滚动容器 否 相对于滚动容器的滚动视口 按计算值类型 按语法 auto 关键字或计算出的 <length-percentage> 值
scroll-padding-left auto | <length-percentage> auto 滚动容器 否 相对于滚动容器的滚动视口 按计算值类型 按语法 auto 关键字或计算出的 <length-percentage> 值
scroll-padding-right auto | <length-percentage> auto 滚动容器 否 相对于滚动容器的滚动视口 按计算值类型 按语法 auto 关键字或计算出的 <length-percentage> 值
scroll-padding-top auto | <length-percentage> auto 滚动容器 否 相对于滚动容器的滚动视口 按计算值类型 按语法 auto 关键字或计算出的 <length-percentage> 值
scroll-snap-align [ none | start | end | center ]{1,2} none 所有元素 否 不适用 离散型 按语法 两个关键字
scroll-snap-stop normal | always normal 所有元素 否 不适用 离散型 按语法 指定关键字
scroll-snap-type none | [ x | y | block | inline | both ] [ mandatory | proximity ]? none 所有元素 否 不适用 离散型 按语法 指定关键字