CSSOM 视图模块

W3C 工作草案,2025 年 9 月 16 日

关于此文档的更多细节
此版本
https://w3org.cn/TR/2025/WD-cssom-view-1-20250916/
最新发布版本
https://w3org.cn/TR/cssom-view-1/
编辑草案
https://drafts.csswg.org/cssom-view/
历史版本
历史
https://w3org.cn/standards/history/cssom-view-1/
反馈
CSS 工作组问题仓库
文档内联
编辑
(Apple Inc)
(Mozilla)
前任编辑
(Opera Software AS)
Glenn Adams (Cox Communications, Inc.)
Anne van Kesteren (Opera Software ASA)
建议编辑此规范
GitHub 编辑器
遗留问题列表
Bugzilla
测试套件
https://wpt.fyi/results/css/cssom-view/

摘要

本规范引入的 API 为作者提供了一种检查和操作文档视觉视图的方法。这包括获取元素布局框的位置、通过脚本获取视口宽度以及滚动元素。

CSS 是一种用于描述结构化文档(如 HTML 和 XML)在屏幕、纸张等介质上渲染方式的语言。

关于本文档

本节描述了本文件发布时的状态。当前 W3C 出版物列表及本技术报告的最新修订版可在 W3C 标准和草案索引中找到。

本文件由 CSS 工作组推荐标准轨道发布为工作草案。发布为工作草案并不意味着 W3C 及其成员的认可。

这是一个草案文档,可能随时会被其他文档更新、替换或废弃。将其作为进展中的工作之外的任何内容进行引用是不恰当的。

请通过 在 GitHub 上提交问题(首选)来发送反馈,并在标题中包含规范代码“cssom-view”,例如:“[cssom-view] …评论摘要…”。所有问题和评论均已 存档。或者,也可以将反馈发送至(已存档的)公共邮件列表 www-style@w3.org

本文件受 2025 年 8 月 18 日 W3C 流程文件的管辖。

本文档由在一个受 W3C 专利政策约束下运作的组织制作。W3C 维护着一份与该组织交付成果相关的专利披露公开列表;该页面还包含了披露专利的说明。任何个人如果确实获知其认为包含必要权利要求 (Essential Claim) 的专利,必须根据 W3C 专利政策第 6 节披露该信息。

1. 背景

本规范中定义的许多功能已得到浏览器长时间的支持。本规范的目标是以一种所有浏览器都能以互操作方式实现这些功能的方式定义它们。本规范还定义了一些允许自定义滚动的新功能。

测试

基础 IDL 测试


2. 术语

本规范使用的术语来自 DOM、CSSOM 和 HTML。[DOM] [CSSOM] [HTML]

如果以下所有条件均为真,则元素 body(即 body 元素)是潜在可滚动的:

注:一个潜在可滚动body 元素可能没有滚动框。例如,它的 overflow 属性的实际值可能是 auto,但其内容并未溢出内容区域。

视口或元素的滚动框 (scrolling box)具有两个溢出方向 (overflow directions),即该视口或元素的块结束内联结束方向。请注意,初始滚动位置可能不与滚动区域原点对齐,具体取决于内容分布属性,请参阅 CSS 框对齐 3 § 5.3 对齐溢出和滚动容器

术语滚动区域 (scrolling area)视口或元素的一个框,它具有以下边缘,具体取决于该视口或元素的滚动框溢出方向

如果溢出方向是……对于视口对于元素
向右和向下
顶部边缘
初始包含块的顶部边缘。
右侧边缘
初始包含块的右侧边缘的最右边缘,以及所有视口后代框的右侧外边距边缘
底部边缘
初始包含块的底部边缘的最底部边缘,以及所有视口后代框的底部外边距边缘
左侧边缘
初始包含块的左侧边缘。
顶部边缘
元素的顶部内边距边缘
右侧边缘
元素右侧内边距边缘的最右边缘,以及所有元素后代框的右侧外边距边缘,不包括那些以该元素的祖先作为其包含块的框。
底部边缘
元素底部内边距边缘的最底部边缘,以及所有元素后代框的底部外边距边缘,不包括那些以该元素的祖先作为其包含块的框。
左侧边缘
元素的左侧内边距边缘
向左和向下
顶部边缘
初始包含块的顶部边缘。
右侧边缘
初始包含块的右侧边缘。
底部边缘
初始包含块的底部边缘的最底部边缘,以及所有视口后代框的底部外边距边缘
左侧边缘
初始包含块的左侧边缘的最左边缘,以及所有视口后代框的左侧外边距边缘
顶部边缘
元素的顶部内边距边缘
右侧边缘
元素的右侧内边距边缘
底部边缘
元素底部内边距边缘的最底部边缘,以及所有元素后代框的底部外边距边缘,不包括那些以该元素的祖先作为其包含块的框。
左侧边缘
元素左侧内边距边缘的最左边缘,以及所有元素后代框的左侧外边距边缘,不包括那些以该元素的祖先作为其包含块的框。
向左和向上
顶部边缘
初始包含块的顶部边缘的最顶部边缘,以及所有视口后代框的顶部外边距边缘
右侧边缘
初始包含块的右侧边缘。
底部边缘
初始包含块的底部边缘。
左侧边缘
初始包含块的左侧边缘的最左边缘,以及所有视口后代框的左侧外边距边缘
顶部边缘
元素顶部内边距边缘的最顶部边缘,以及所有元素后代框的顶部外边距边缘,不包括那些以该元素的祖先作为其包含块的框。
右侧边缘
元素的右侧内边距边缘
底部边缘
元素的底部内边距边缘
左侧边缘
元素左侧内边距边缘的最左边缘,以及所有元素后代框的左侧外边距边缘,不包括那些以该元素的祖先作为其包含块的框。
向右和向上
顶部边缘
初始包含块的顶部边缘的最顶部边缘,以及所有视口后代框的顶部外边距边缘
右侧边缘
初始包含块的右侧边缘的最右边缘,以及所有视口后代框的右侧外边距边缘
底部边缘
初始包含块的底部边缘。
左侧边缘
初始包含块的左侧边缘。
顶部边缘
元素顶部内边距边缘的最顶部边缘,以及所有元素后代框的顶部外边距边缘,不包括那些以该元素的祖先作为其包含块的框。
右侧边缘
元素右侧内边距边缘的最右边缘,以及所有元素后代框的右侧外边距边缘,不包括那些以该元素的祖先作为其包含块的框。
底部边缘
元素的底部内边距边缘
左侧边缘
元素的左侧内边距边缘

滚动区域原点 (origin),如果是视口,则为初始包含块的原点;否则为元素处于默认滚动位置时的顶部左侧内边距边缘。x 坐标向右增加,y 坐标向下增加。

框或元素的一组特定边缘的起始边缘 (beginning edges)是指以下边缘

如果溢出方向是向右和向下
顶部和左侧边缘。
如果溢出方向是向左和向下
顶部和右侧边缘。
如果溢出方向是向左和向上
底部和右侧边缘。
如果溢出方向是向右和向上
底部和左侧边缘。

框或元素的一组特定边缘的结束边缘 (ending edges)是指以下边缘

如果溢出方向是向右和向下
底部和右侧边缘。
如果溢出方向是向左和向下
底部和左侧边缘。
如果溢出方向是向左和向上
顶部和左侧边缘。
如果溢出方向是向右和向上
顶部和右侧边缘。

可视视口 (visual viewport)是一种视口,其滚动区域是另一个视口,称为布局视口 (layout viewport)

除了滚动之外,可视视口还可以对其布局视口应用缩放变换。此变换应用于布局视口画布,并且不影响其内部坐标空间。

注:可视视口的缩放变换通常被称为“捏合缩放 (pinch-zoom)”。在概念上,此变换改变了 CSS 参考像素的大小,但按比例改变了布局视口的大小,因此不会导致页面内容的重排。

缩放变换的大小被称为可视视口缩放因子 (scale factor)

此动画展示了一个缩放后的可视视口被“平移”(例如,通过用户进行触摸拖动)的示例。页面被缩放,使得布局视口大于可视视口。

滚动增量首先应用于可视视口。当可视视口处于其范围边界时,滚动增量将应用于布局视口。此行为由执行滚动步骤实现。

Document Layout Viewport Visual Viewport

VisualViewport 对象具有一个关联文档,这是一个 Document 对象。它是 VisualViewport 的所有者 Window关联文档布局视口是所有者 Window视口

为了满足本规范中的要求,display 属性的计算值为 table-columntable-column-group 的元素必须被视为具有关联的(分别为列或列组)。

术语SVG 布局框指由 SVG 元素生成的、不对应于 CSS 定义的 display 类型的。(例如由 rect 元素生成的。)

术语变换 (transforms)指 SVG 变换和 CSS 变换。[SVG11] [CSS-TRANSFORMS-1]

当一个方法或属性被说成是调用另一个方法或属性时,用户代理必须为该属性或方法调用其内部 API,以便例如作者不能通过使用 ECMAScript 中的自定义属性或函数覆盖属性或方法来更改行为。

除非另有说明,所有字符串比较均使用 is

2.1. CSS 像素

除非另有说明,本规范定义的 API 的所有坐标和尺寸均以 CSS 像素为单位。[CSS-VALUES]

注:这不适用于例如 matchMedia(),因为其单位已明确给出。

2.2. 缩放

有两种缩放类型:页面缩放 (page zoom),它影响初始视口的大小;以及可视视口缩放因子,它像放大镜一样工作,不会影响初始视口或实际视口。[CSS-DEVICE-ADAPT]

注:“缩放因子”通常被称为“捏合缩放”;然而,它可以通过捏合缩放以外的方式受到影响。例如,用户代理可能会放大聚焦的输入元素以使其清晰可见。

2.3. Web 暴露的屏幕信息

用户代理可以选择隐藏有关输出设备屏幕的信息,以保护用户隐私。为了在不同 API 中以一致的方式执行此操作,本规范定义了以下术语,每个术语都具有宽度和高度,原点为左上角,x 和 y 坐标分别向右和向下增加。

Web 暴露的屏幕区域是以下之一:

Web 暴露的可用屏幕区域是以下之一:

3. 通用基础设施

本规范依赖于 WHATWG Infra 标准。[INFRA]

3.1. 滚动

当用户代理要对滚动框 box 执行滚动到给定位置 position,以及关联的元素或伪元素 element,并可选地设置滚动行为 behavior(如果省略则为“auto”)时,必须运行以下步骤:

  1. 中止 box 正在进行的任何平滑滚动
  2. 如果用户代理遵循 scroll-behavior 属性,且以下任一条件为真:
    • behavior 为 "auto",且 element 不为 null,且其 scroll-behavior 属性的计算值为 smooth
    • behaviorsmooth
    ……则对 box 执行到 position平滑滚动。一旦位置更新完成,触发 scrollend 事件。否则,对 box 执行到 position即时滚动。在即时滚动之后,触发 scrollend 事件。

    注:behavior: "instant" 始终通过此算法执行即时滚动

    注:如果滚动位置并未因用户交互或程序调用而发生变化,且没有因操作而应用任何位移,则不会触发 scrollend 事件,因为没有发生滚动。

当用户代理要对视口执行滚动到给定位置 position,并可选地设置滚动行为 behavior(如果省略则为“auto”)时,它必须通过以下步骤执行协调的视口滚动:

  1. doc视口的关联 Document

  2. vv关联文档docVisualViewport

  3. maxX视口滚动框的宽度与 vvwidth 属性值之差。

  4. maxY视口滚动框的高度与 vvheight 属性值之差。

  5. dxposition 的水平分量减去 vvpageLeft 属性值。

  6. dyposition 的垂直分量减去 vvpageTop 属性值。

  7. visual xvvoffsetLeft 属性值。

  8. visual yvvoffsetTop 属性值。

  9. visual dx 为 min(maxX, max(0, visual x + dx)) - visual x

  10. visual dy 为 min(maxY, max(0, visual y + dy)) - visual y

  11. layout dxdx - visual dx

  12. layout dydy - visual dy

  13. elementdoc 的根元素(如果存在),否则为 null。

  14. 执行视口滚动框的滚动,位置为当前滚动位置 + (layout dx, layout dy),关联元素为 element,滚动行为为 behavior

  15. 执行 vv 滚动框的滚动,位置为当前滚动位置 + (visual dx, visual dy),关联元素为 element,滚动行为为 behavior

注:从概念上讲,可视视口会滚动,直到它“碰到”布局视口的边缘,然后通过将滚动增量应用于布局视口来“推动”布局视口。然而,上述步骤中的滚动是提前计算的,并以相反的顺序应用,以便在可视视口之前滚动布局视口。这是出于历史原因,以确保一致的滚动事件排序。有关视觉演示,请参阅上面的示例

用户捏合缩放进入文档并拨动鼠标滚轮,请求用户代理将文档向下滚动 50px。由于文档处于捏合缩放状态,可视视口有 20px 的滚动空间。用户代理通过将可视视口向下滚动 20px、将布局视口向下滚动 30px 来分配滚动。
用户正在移动设备用户代理中查看文档。文档聚焦了一个屏幕外的文本输入元素,显示了一个缩小可视视口的虚拟键盘。用户代理现在必须将该元素带入可视视口。用户代理滚动布局视口,使元素在其中可见,然后滚动可视视口,使元素对用户可见。

当滚动位置没有更多待处理的更新或位移,且用户已完成手势时,滚动即完成。滚动位置更新包括平滑或即时鼠标滚轮滚动、键盘滚动、滚动捕获事件或其他导致滚动位置更新并可能插值的 API 和手势。触摸平移或触控板滚动等用户手势直到指针或按键释放才算完成。

当用户代理要对滚动框 box 执行平滑滚动position 时,它必须以用户代理定义的方式在用户代理定义的时间内更新 box 的滚动位置。当滚动完成时,box 的滚动位置必须为 position。滚动也可以被中止,可以通过算法或用户操作。

当用户代理要对滚动框 box 执行即时滚动position 时,它必须将 box 的滚动位置更新为 position

要对文档 document 滚动到文档开头,请遵循以下步骤:

  1. viewport 为与 document 关联的视口
  2. positionviewport 通过将滚动区域起始边缘viewport起始边缘对齐时会拥有的滚动位置。
  3. 如果 positionviewport 当前的滚动位置相同,且 viewport 没有进行中的平滑滚动,则中止这些步骤。
  4. viewport 执行滚动到 position,并以 document根元素作为关联元素(如果存在),否则为 null。

注:此算法用于导航到 #top 片段标识符时,如 HTML 中定义的那样。[HTML]

测试

3.2. WebIDL 值

当被要求对值 x 规范化非有限值 时,如果 x 是三个特殊浮点字面量值(Infinity-InfinityNaN)之一,则 x 必须更改为值 0[WEBIDL]

4. Window 接口的扩展
enum ScrollBehavior { "auto", "instant", "smooth" };

dictionary ScrollOptions {
    ScrollBehavior behavior = "auto";
};
dictionary ScrollToOptions : ScrollOptions {
    unrestricted double left;
    unrestricted double top;
};

partial interface Window {
    [NewObject] MediaQueryList matchMedia(CSSOMString query);
    [SameObject, Replaceable] readonly attribute Screen screen;
    [SameObject, Replaceable] readonly attribute VisualViewport? visualViewport;

    // browsing context
    undefined moveTo(long x, long y);
    undefined moveBy(long x, long y);
    undefined resizeTo(long width, long height);
    undefined resizeBy(long x, long y);

    // viewport
    [Replaceable] readonly attribute long innerWidth;
    [Replaceable] readonly attribute long innerHeight;

    // viewport scrolling
    [Replaceable] readonly attribute double scrollX;
    [Replaceable] readonly attribute double pageXOffset;
    [Replaceable] readonly attribute double scrollY;
    [Replaceable] readonly attribute double pageYOffset;
    undefined scroll(optional ScrollToOptions options = {});
    undefined scroll(unrestricted double x, unrestricted double y);
    undefined scrollTo(optional ScrollToOptions options = {});
    undefined scrollTo(unrestricted double x, unrestricted double y);
    undefined scrollBy(optional ScrollToOptions options = {});
    undefined scrollBy(unrestricted double x, unrestricted double y);

    // client
    [Replaceable] readonly attribute long screenX;
    [Replaceable] readonly attribute long screenLeft;
    [Replaceable] readonly attribute long screenY;
    [Replaceable] readonly attribute long screenTop;
    [Replaceable] readonly attribute long outerWidth;
    [Replaceable] readonly attribute long outerHeight;
    [Replaceable] readonly attribute double devicePixelRatio;
};

当调用 matchMedia(query) 方法时,必须运行这些步骤:

  1. parsed media query list解析 query 的结果。
  2. 返回一个新的 MediaQueryList 对象,其文档this关联 Document,其媒体查询列表parsed media query list
测试

screen 属性必须返回与 Window 对象关联的 Screen 对象。

注:Document 导航时,通过 WindowProxy 对象访问 screen 可能会产生不同的结果。

如果关联文档处于完全活动 (fully active)状态,visualViewport 属性必须返回与 Window 对象的关联文档相关联的 VisualViewport 对象。否则,它必须返回 null。

注:VisualViewport 对象仅对文档当前正在呈现的窗口返回且有用。如果保留了对文档当前未呈现的 VisualViewport 的引用,则该 VisualViewport 中的值不得泄露任何有关浏览上下文的信息。

测试

当调用 moveTo(x, y) 方法时,必须遵循以下步骤:

  1. 可选地,返回。

  2. targetthis相关全局对象浏览上下文

  3. 如果 target 不是由脚本(而不是由用户操作)创建的辅助浏览上下文,则返回。

  4. 可选地,以用户代理定义的方式限制 xy,使窗口不会移出可用空间。

  5. 移动 target 的窗口,使窗口的左上角位于相对于输出设备左上角的坐标 (x, y) 处,以 targetCSS 像素为单位。正轴方向为向右和向下。

当调用 moveBy(x, y) 方法时,必须遵循以下步骤:

  1. 可选地,返回。

  2. targetthis相关全局对象浏览上下文

  3. 如果 target 不是由脚本(而不是由用户操作)创建的辅助浏览上下文,则返回。

  4. 可选地,以用户代理定义的方式限制 xy,使窗口不会移出可用空间。

  5. target 的窗口向右移动 xtargetCSS 像素,向下移动 ytargetCSS 像素

当调用 resizeTo(width, height) 方法时,必须遵循以下步骤:

  1. 可选地,返回。

  2. targetthis相关全局对象浏览上下文

  3. 如果 target 不是由脚本(而不是由用户操作)创建的辅助浏览上下文,则返回。

  4. 可选地,以用户代理定义的方式限制 widthheight,使窗口不会变得太小或超过可用空间。

  5. 通过移动其右侧和底部边缘来调整 target 的窗口大小,使得视口左右边缘之间的距离为 widthtargetCSS 像素,视口顶部和底部边缘之间的距离为 heighttargetCSS 像素

  6. 可选地,以用户代理定义的方式移动 target 的窗口,使其不会增长到可用空间之外。

测试

当调用 resizeBy(x, y) 方法时,必须遵循以下步骤:

  1. 可选地,返回。

  2. targetthis相关全局对象浏览上下文

  3. 如果 target 不是由脚本(而不是由用户操作)创建的辅助浏览上下文,则返回。

  4. 可选地,以用户代理定义的方式限制 xy,使窗口不会变得太小或超过可用空间。

  5. 通过将右侧边缘向右移动 xtargetCSS 像素,将底部边缘向下移动 ytargetCSS 像素来调整 target 的窗口大小。

  6. 可选地,以用户代理定义的方式移动 target 的窗口,使其不会增长到可用空间之外。

innerWidth 属性必须返回包含呈现的滚动条(如有)尺寸的视口宽度,如果没有视口,则返回零。

下面的代码片段展示了如何获取视口的宽度:var viewportWidth = innerWidth

innerHeight 属性必须返回包含呈现的滚动条(如有)尺寸的视口高度,如果没有视口,则返回零。

scrollX 属性必须返回相对于初始包含块原点的视口左侧 x 坐标,如果没有视口,则返回零。

pageXOffset 属性必须返回由 scrollX 属性返回的值。

scrollY 属性必须返回相对于初始包含块原点的视口顶部 y 坐标,如果没有视口,则返回零。

pageYOffset 属性必须返回由 scrollY 属性返回的值。

当调用 scroll() 方法时,必须运行这些步骤:

  1. 如果使用一个参数调用,请遵循以下子步骤:

    1. options 为该参数。

    2. xoptionsleft 字典成员的值(如果存在),否则为视口当前在 x 轴上的滚动位置。

    3. yoptionstop 字典成员的值(如果存在),否则为视口当前在 y 轴上的滚动位置。

  2. 如果使用两个参数调用,请遵循以下子步骤:

    1. options 为 null 转换ScrollToOptions 字典。[WEBIDL]

    2. xy 分别为这两个参数。

  3. 规范化 xy 的非有限值。

  4. 如果没有视口,则中止这些步骤。

  5. viewport width视口的宽度,不包括滚动条的宽度(如有)。

  6. viewport height视口的高度,不包括滚动条的高度(如有)。

  7. 如果视口具有向右的溢出方向
    x 为 max(0, min(x, 视口 滚动区域宽度 - viewport width))。
    如果视口具有向左的溢出方向
    x 为 min(0, max(x, viewport width - 视口 滚动区域宽度))。
  8. 如果视口具有向下的溢出方向
    y 为 max(0, min(y, 视口 滚动区域高度 - viewport height))。
    如果视口具有向上的溢出方向
    y 为 min(0, max(y, viewport height - 视口 滚动区域高度))。
  9. position视口通过将视口滚动区域的 x 坐标 x视口左侧对齐,并将视口滚动区域的 y 坐标 y视口顶部对齐所具有的滚动位置。

  10. 如果 position视口当前滚动位置相同,且视口没有进行中的平滑滚动,则中止这些步骤。

  11. document视口关联的 Document

  12. 执行滚动操作,将视口滚动至 position,并以 document根元素(如果存在)作为关联元素,否则为 null;滚动行为取自 optionsbehavior 字典成员的值。

    用户代理对于此操作是使用(协调的)视口执行滚动,还是在布局视口的滚动框上使用滚动框执行滚动,尚无共识。

测试

scrollTo() 方法被调用时,用户代理必须表现为调用了带有相同参数的 scroll() 方法。

测试

scrollBy() 方法被调用时,用户代理必须执行以下步骤

  1. 如果使用两个参数调用,请遵循以下子步骤:

    1. options转换ScrollToOptions 字典的 null 值。[WEBIDL]

    2. xy 分别为这两个参数。

    3. optionsleft 字典成员的值为 x

    4. optionstop 字典成员的值为 y

  2. 规范化 optionslefttop 字典成员的非有限值。

  3. scrollX 的值加到 left 字典成员中。

  4. scrollY 的值加到 top 字典成员中。

  5. 表现为调用了以 options 为唯一参数的 scroll() 方法。

screenXscreenLeft 属性必须返回客户端窗口左侧相对于网络公开屏幕区域原点的 x 坐标(以 CSS 像素为单位),如果不存在则返回 0。

测试

screenYscreenTop 属性必须返回客户端窗口顶部相对于网络公开屏幕区域的屏幕原点的 y 坐标(以 CSS 像素为单位),如果不存在则返回 0。

outerWidth 属性必须返回客户端窗口的宽度。如果没有客户端窗口,则此属性必须返回 0。

outerHeight 属性必须返回客户端窗口的高度。如果没有客户端窗口,则此属性必须返回 0。

devicePixelRatio 属性必须返回执行以下确定设备像素比算法的结果。

  1. 如果没有输出设备,则返回 1 并中止这些步骤。

  2. CSS pixel size 为在当前页面缩放下且使用 1.0 的缩放因子时,一个CSS 像素的大小。

  3. device pixel size 为输出设备一个设备像素的垂直尺寸。

  4. 返回 CSS pixel size 除以 device pixel size 的结果。

4.1. open() 方法的 features 参数

HTML 定义了 open() 方法。本节定义了 features 参数中给出的位置和大小的行为。[HTML]

针对给定映射 tokenizedFeatures 的浏览上下文 target设置浏览上下文特性

  1. x 为 null。

  2. y 为 null。

  3. width 为 null。

  4. height 为 null。

  5. 如果 tokenizedFeatures["left"] 存在

    1. x 设置为对 tokenizedFeatures["left"] 调用整数解析规则的结果。

    2. 如果 x 是一个错误,则将 x 设置为 0。

    3. 可选地,以用户代理定义的方式对 x 进行钳制,以使窗口不会移出网络公开可用屏幕区域

    4. 可选地,移动 target 的窗口,使其左边缘位于相对于网络公开屏幕区域左边缘的水平坐标 x 处,该坐标以 targetCSS 像素测量。正轴向右。

  6. 如果 tokenizedFeatures["top"] 存在

    1. y 设置为对 tokenizedFeatures["top"] 调用整数解析规则的结果。

    2. 如果 y 是一个错误,则将 y 设置为 0。

    3. 可选地,以用户代理定义的方式对 y 进行钳制,以使窗口不会移出网络公开可用屏幕区域

    4. 可选地,移动 target 的窗口,使其顶部边缘位于相对于网络公开屏幕区域顶部边缘的垂直坐标 y 处,该坐标以 targetCSS 像素测量。正轴向下。

  7. 如果 tokenizedFeatures["width"] 存在

    1. width 设置为对 tokenizedFeatures["width"] 调用整数解析规则的结果。

    2. 如果 width 是一个错误,则将 width 设置为 0。

    3. 如果 width 不为 0

      1. 可选地,以用户代理定义的方式对 width 进行钳制,以使窗口不会变得太小或大于网络公开可用屏幕区域

      2. 可选地,通过移动其右边缘来调整 target 窗口的大小,使得视口左右边缘之间的距离为 targetwidthCSS 像素

      3. 可选地,以用户代理定义的方式移动 target 的窗口,使其不会增长到网络公开可用屏幕区域之外。

  8. 如果 tokenizedFeatures["height"] 存在

    1. height 设置为对 tokenizedFeatures["height"] 调用整数解析规则的结果。

    2. 如果 height 是一个错误,则将 height 设置为 0。

    3. 如果 height 不为 0

      1. 可选地,以用户代理定义的方式对 height 进行钳制,以使窗口不会变得太小或大于网络公开可用屏幕区域

      2. 可选地,通过移动其底边来调整 target 窗口的大小,使得视口顶部和底部边缘之间的距离为 targetheightCSS 像素

      3. 可选地,以用户代理定义的方式移动 target 的窗口,使其不会增长到网络公开可用屏幕区域之外。

支持的 open() 特性名称 是以下之一:

width
视口的宽度。
height
视口的高度。
left
窗口的左侧位置。
top
窗口的顶部位置。

4.2. MediaQueryList 接口

本节与 HTML 中定义的事件循环集成。[HTML]

MediaQueryList 对象在创建时拥有一个关联的媒体查询列表和一个关联的文档

MediaQueryList 对象有一个关联的媒体,它是关联媒体查询列表序列化形式。

MediaQueryList 对象有一个关联的匹配状态,如果关联的媒体查询列表文档的状态匹配,则为 true,否则为 false。

当被要求为 Document doc 评估媒体查询并报告更改时,运行以下步骤:

  1. 对于每个以 doc 作为其文档MediaQueryList 对象 target,按它们创建的顺序(最旧的优先)运行以下子步骤:

    1. 如果 target匹配状态自上次运行这些步骤以来已更改,则在 target触发一个名为 change 的事件,使用 MediaQueryListEvent,其 isTrusted 属性初始化为 true,其 media 属性初始化为 target媒体,其 matches 属性初始化为 target匹配状态
一段检测视口方向变化的代码可以编写如下:
function handleOrientationChange(event) {
    if(event.matches) // landscapeelse}
var mql = matchMedia("(orientation:landscape)");
mql.onchange = handleOrientationChange;
[Exposed=Window]
interface MediaQueryList : EventTarget {
  readonly attribute CSSOMString media;
  readonly attribute boolean matches;
  undefined addListener(EventListener? callback);
  undefined removeListener(EventListener? callback);
           attribute EventHandler onchange;
};

media 属性必须返回关联的媒体

matches 属性必须返回关联的匹配状态

addListener(callback) 方法在被调用时必须运行以下步骤:

  1. 添加一个事件监听器,其目标为 this,且为一个事件监听器,其 类型change,且回调callback

removeListener(callback) 方法在被调用时必须运行以下步骤:

  1. 如果 this事件监听器列表包含一个事件监听器,其 类型change回调callback,且捕获为 false,则移除事件监听器,目标为 this,并移除该事件监听器

注意:本规范最初有一种自定义回调机制,使用 addListener()removeListener(),并以关联的媒体查询列表作为参数调用回调。现在改用常规的事件机制。为了向后兼容,addListener()removeListener() 方法基本上分别别名为 addEventListener()removeEventListener(),且 change 事件假装为一个 MediaQueryList

以下是所有实现 MediaQueryList 接口的对象必须支持的事件处理器(及其对应的事件处理器事件类型),作为事件处理器 IDL 属性

事件处理器 事件处理器事件类型
onchange change
测试
[Exposed=Window]
interface MediaQueryListEvent : Event {
  constructor(CSSOMString type, optional MediaQueryListEventInit eventInitDict = {});
  readonly attribute CSSOMString media;
  readonly attribute boolean matches;
};

dictionary MediaQueryListEventInit : EventInit {
  CSSOMString media = "";
  boolean matches = false;
};

media 属性必须返回它被初始化为的值。

matches 属性必须返回它被初始化为的值。

4.2.1. 事件摘要

本节是非规范性的。

EventInterface感兴趣的目标描述
change MediaQueryListEvent MediaQueryList 匹配状态发生变化时,在 MediaQueryList 上触发。

4.3. Screen 接口

顾名思义,Screen 接口代表有关输出设备屏幕的信息。

[Exposed=Window]
interface Screen {
  readonly attribute long availWidth;
  readonly attribute long availHeight;
  readonly attribute long width;
  readonly attribute long height;
  readonly attribute unsigned long colorDepth;
  readonly attribute unsigned long pixelDepth;
};

availWidth 属性必须返回网络公开可用屏幕区域的宽度。

availHeight 属性必须返回网络公开可用屏幕区域的高度。

width 属性必须返回网络公开屏幕区域的宽度。

height 属性必须返回网络公开屏幕区域的高度。

colorDepthpixelDepth 属性应返回为输出设备中的像素分配的颜色位数,不包括 alpha 通道。如果用户代理无法返回输出设备使用的位数,则应返回最接近的估计值,例如,发送到显示器的帧缓冲使用的位数或任何最接近输出设备将使用的值的内部表示。用户代理对于这些属性返回的值必须至少等于color媒体特性值乘以 3。如果不同的颜色分量不是用相同数量的位数表示的,则返回值可能大于color媒体特性值的 3 倍。如果用户代理不知道色深或者出于隐私考虑不想返回该值,则应返回 24。

注意:出于兼容性原因,colorDepthpixelDepth 属性返回相同的值。

注意:已知一些不符合规范的实现返回 32 而不是 24。

测试

5. Document 接口的扩展

partial interface Document {
  Element? elementFromPoint(double x, double y);
  sequence<Element> elementsFromPoint(double x, double y);
  CaretPosition? caretPositionFromPoint(double x, double y, optional CaretPositionFromPointOptions options = {});
  readonly attribute Element? scrollingElement;
};

dictionary CaretPositionFromPointOptions {
  sequence<ShadowRoot> shadowRoots = [];
};

elementFromPoint(x, y) 方法必须遵循以下步骤:

  1. 如果任一参数为负,x 大于视口宽度减去渲染滚动条的大小(如果有),y 大于视口高度减去渲染滚动条的大小(如果有),或者没有与文档关联的视口,则返回 null 并终止这些步骤。

  2. 如果视口中存在一个盒子,在应用适用于视口后代的变换时,该盒子在坐标 x,y 处是点击测试的目标,则返回关联的元素并终止这些步骤。

  3. 如果文档有根元素,则返回根元素并终止这些步骤。

  4. 返回 null。

注意:elementFromPoint() 方法不一定返回最顶层的绘制元素。例如,可以使用 pointer-events CSS 属性将元素排除在点击测试目标之外。

测试

elementsFromPoint(x, y) 方法必须遵循以下步骤:

  1. sequence 为一个新的空序列。

  2. 如果任一参数为负,x 大于视口宽度减去渲染滚动条的大小(如果有),y 大于视口高度减去渲染滚动条的大小(如果有),或者没有与文档关联的视口,则返回 sequence 并终止这些步骤。

  3. 对于视口中的每个盒子,按绘制顺序(从最顶层的盒子开始),在应用适用于视口后代的变换时,即使没有东西会重叠它,只要该盒子在坐标 x,y 处是点击测试的目标,就将其关联元素追加到 sequence 中。

  4. 如果文档有根元素,并且 sequence 中的最后一项不是根元素,则将根元素追加到 sequence 中。

  5. 返回 sequence

测试

caretPositionFromPoint(x, y, options) 方法必须返回运行以下步骤的结果:

  1. 如果没有与文档关联的视口,则返回 null。

  2. 如果任一参数为负,x 大于视口宽度减去渲染滚动条的大小(如果有),y 大于视口高度减去渲染滚动条的大小(如果有),则返回 null。

  3. 如果视口坐标 x,y 处在应用适用于视口后代的变换时,不会插入任何文本插入点指示符,则返回 null。

  4. 如果视口坐标 x,y 处在应用适用于视口后代的变换时,文本插入点指示符会在一个同时也是被替换元素的文本输入小部件中插入,则返回一个插入符号位置,并设置其属性如下:

    插入符号节点
    对应文本输入小部件的节点。
    插入符号偏移量
    文本插入点指示符插入位置左侧的 16 位单元数量。
  5. 否则

    1. caretPosition 为一个元组,由 caretPositionNode(一个节点)和 caretPositionOffset(一个非负整数)组成,用于表示在应用适用于视口后代的变换时,文本插入点指示符应插入的位置。

    2. startNodecaretPositioncaretPositionNode,令 startOffsetcaretPositioncaretPositionOffset

    3. startNode 是一个节点startNode是一个影子根,且 startNode不是 options["shadowRoots"] 中任何一项的包含影子根的包含祖先时,重复执行这些步骤:

      1. startOffset 设置为 startNode宿主索引

      2. startNode 设置为 startNode宿主父节点

    4. 返回一个插入符号位置,并设置其属性如下:

      1. 插入符号节点设置为 startNode

      2. 插入符号偏移量设置为 startOffset

注意:插入符号位置不是实时的。

注意:点击测试的具体细节超出了本规范的范围,因此 elementFromPoint()caretPositionFromPoint() 的确切细节也超出范围。点击测试有望在 CSS 或 HTML 的未来版本中定义。

Document 接口上的 scrollingElement 属性在获取时必须运行以下步骤:

  1. 如果 Document 处于怪异模式,则遵循以下子步骤:

    1. 如果body 元素存在,且它不是潜在可滚动的,则返回body 元素并中止这些步骤。

      为此,body 元素的父元素上的 overflow:clip 值必须被视为 overflow:hidden

    2. 返回 null 并中止这些步骤。

  2. 如果存在根元素,则返回根元素并中止这些步骤。

  3. 返回 null。

注意:对于始终对 scrollTopscrollLeft 使用怪异模式行为的不符合规范的用户代理,scrollingElement 属性预计也应始终返回body 元素(如果不存在则返回 null)。此 API 的存在是为了让 Web 开发人员可以使用它来获取用于滚动 API 的正确元素,而无需对特定用户代理的行为做出假设,也不必为了确定哪个元素滚动视口而触发滚动。

注意:body 元素与 HTML 的 document.body 不同,后者可以返回 frameset 元素。

测试

5.1. CaretPosition 接口

插入符号位置给出了文本插入点指示符的位置。它总是拥有一个关联的插入符号节点插入符号偏移量。它由 CaretPosition 对象表示。

[Exposed=Window]
interface CaretPosition {
  readonly attribute Node offsetNode;
  readonly attribute unsigned long offset;
  [NewObject] DOMRect? getClientRect();
};

offsetNode 属性必须返回插入符号节点

offset 属性必须返回插入符号偏移量

getClientRect() 方法必须遵循以下步骤,在第一个返回值的步骤中止:

  1. 如果插入符号节点是一个被替换元素的文本输入小部件,并且该部件在文档中,则返回一个由插入符号偏移量值表示的、该部件中插入符号的缩放 DOMRect 对象。将适用于该元素及其祖先的变换应用上去。

  2. 否则

    1. caretRange 为一个折叠的 Range 对象,其开始节点结束节点被设置为插入符号节点,且其开始偏移量结束偏移量被设置为插入符号偏移量

    2. 返回在 caretRange 上调用 getBoundingClientRect() 方法所得到的 DOMRect 对象。

注意:DOMRect 对象不是实时的。

测试

6. Element 接口的扩展

enum ScrollLogicalPosition { "start", "center", "end", "nearest" };
dictionary ScrollIntoViewOptions : ScrollOptions {
  ScrollLogicalPosition block = "start";
  ScrollLogicalPosition inline = "nearest";
  ScrollIntoViewContainer container = "all";
};

enum ScrollIntoViewContainer { "all", "nearest" };

dictionary CheckVisibilityOptions {
    boolean checkOpacity = false;
    boolean checkVisibilityCSS = false;
    boolean contentVisibilityAuto = false;
    boolean opacityProperty = false;
    boolean visibilityProperty = false;
};

partial interface Element {
  DOMRectList getClientRects();
  [NewObject] DOMRect getBoundingClientRect();

  boolean checkVisibility(optional CheckVisibilityOptions options = {});

  undefined scrollIntoView(optional (boolean or ScrollIntoViewOptions) arg = {});
  undefined scroll(optional ScrollToOptions options = {});
  undefined scroll(unrestricted double x, unrestricted double y);
  undefined scrollTo(optional ScrollToOptions options = {});
  undefined scrollTo(unrestricted double x, unrestricted double y);
  undefined scrollBy(optional ScrollToOptions options = {});
  undefined scrollBy(unrestricted double x, unrestricted double y);
  attribute unrestricted double scrollTop;
  attribute unrestricted double scrollLeft;
  readonly attribute long scrollWidth;
  readonly attribute long scrollHeight;
  readonly attribute long clientTop;
  readonly attribute long clientLeft;
  readonly attribute long clientWidth;
  readonly attribute long clientHeight;
  readonly attribute double currentCSSZoom;
};

注意:checkOpacitycheckVisibilityCSS 属性是历史名称。这些属性具有符合新命名方案的别名,即 opacityPropertyvisibilityProperty

getClientRects() 方法在被调用时,必须返回以下算法的结果:

  1. 如果调用该方法的元素没有关联的盒子,则返回一个空的 DOMRectList 对象并停止此算法。

  2. 如果该元素拥有一个关联的 SVG 布局盒子,则返回一个缩放DOMRectList 对象,其中包含一个描述 SVG 规范定义的元素边框盒子的 DOMRect 对象,并应用适用于该元素及其祖先的变换

  3. 返回一个 DOMRectList 对象,按内容顺序包含为每个盒子片段准备的 DOMRect 对象,描述其边框区域(包括高度或宽度为零的区域),并带有以下约束:

    • 应用适用于该元素及其祖先的变换

    • 如果调用该方法的元素的 display 属性计算值为 tableinline-table,则包含表格盒子和标题盒子(如果有),但不包含匿名容器盒子。

    • 用其子盒子替换每个匿名块盒子,并重复此过程直到最终列表中不再有匿名块盒子。

注意:getClientRects() 返回的 DOMRect 对象不是实时的。

测试

getBoundingClientRect() 方法在对元素 element 调用时,必须返回获取边框盒 element 的结果。

获取边框盒 element,请运行以下步骤:
  1. list 为在 element 上调用 getClientRects() 的结果。

  2. 如果 list 为空,则返回一个 DOMRect 对象,其 xywidthheight 成员均为 0。

  3. 如果 list 中的所有矩形宽度或高度均为 0,则返回 list 中的第一个矩形。

  4. 否则,返回一个 DOMRect 对象,描述包含 list 中所有高度或宽度不为 0 的矩形的最小矩形。

注意:getBoundingClientRect() 返回的 DOMRect 对象不是实时的。

以下代码片段获取文档中第一个 div 元素的尺寸:
var example = document.getElementsByTagName("div")[0].getBoundingClientRect();
var exampleWidth = example.width;
var exampleHeight = example.height;
测试
注意:checkVisibility() 方法提供了一组简单的检查,用于判断元素是否潜在地“可见”。它默认基于盒模型树采用一种非常简单直接的方法,但同时也允许根据所期望的“可见性”精确概念,选择加入若干额外的检查。

当在元素 this 上调用时,checkVisibility(options) 方法必须执行以下步骤

  1. 如果 this 没有关联的盒模型,则返回 false。

  2. 如果 this扁平树中的祖先元素具有 content-visibility: hidden,则返回 false。

  3. 如果 optionsopacityPropertycheckOpacity 字典成员中任意一个为 true,且 this(或 this扁平树中的祖先)的计算后 opacity 值为 0,则返回 false。

  4. 如果 optionsvisibilityPropertycheckVisibilityCSS 字典成员中任意一个为 true,且 this不可见的,则返回 false。

  5. 如果 optionscontentVisibilityAuto 字典成员为 true,且 this扁平树中的某个祖先因为 content-visibility: auto跳过其内容,则返回 false。

  6. 返回 true。

测试

scrollIntoView(arg) 方法被调用时,必须执行以下步骤

  1. behavior 为 "auto"。

  2. block 为 "start"。

  3. inline 为 "nearest"。

  4. containernull

  5. 如果 arg 是一个 ScrollIntoViewOptions 字典,那么

    1. behavior 设置为 optionsbehavior 字典成员。

    2. block 设置为 optionsblock 字典成员。

    3. inline 设置为 optionsinline 字典成员。

    4. 如果 optionscontainer 字典成员为 "nearest",则将 container 设置为该元素。

  6. 否则,如果 arg 为 false,则将 block 设置为 "end"。

  7. 如果该元素没有关联的盒模型,或者对于用户代理功能不可用,则返回。

  8. behaviorblockinlinecontainer 将该元素滚动到视图中

  9. 可选地执行某些其他引起用户注意该元素的操作。

组件可以使用 scrollIntoView 将相关内容滚动至指定的对齐方式
<style>
    .scroller { overflow: auto; scroll-padding: 8px; }
    .slide { scroll-margin: 16px; scroll-snap-align: center; }
</style>
<div class="carousel">
    <div class="slides scroller">
        <div id="s1" class="slide">
        <div id="s2" class="slide">
        <div id="s3" class="slide">
    </div>
    <div class="markers">
        <button data-target="s1">1</button>
        <button data-target="s2">2</button>
        <button data-target="s3">3</button>
    </div>
</div>
<script>
    document.querySelector('.markers').addEventListener('click', (evt) => {
        const target = document.getElementById(evt.target.dataset.target);
        if (!target) return;
        // scrollIntoView correctly aligns target item respecting scroll-snap-align,
        // scroll-margin, and the scroll container’s scroll-padding.
        target.scrollIntoView({
            // Only scroll the nearest scroll container.
            container: 'nearest',
            behavior: 'smooth'
        });
    });
</script>
测试

scroll() 方法被调用时,必须执行以下步骤

  1. 如果使用一个参数调用,请遵循以下子步骤:

    1. options 为该参数。

    2. 如果存在,归一化 lefttop 字典成员的非有限值。

    3. xleft 字典成员的值(如果存在),否则为该元素在 x 轴上的当前滚动位置。

    4. ytop 字典成员的值(如果存在),否则为该元素在 y 轴上的当前滚动位置。

  2. 如果使用两个参数调用,请遵循以下子步骤:

    1. options 设为 null,并转换ScrollToOptions 字典。[WEBIDL]

    2. xy 分别为这两个参数。

    3. 归一化 xy 的非有限值。

    4. optionsleft 字典成员设为值 x

    5. optionstop 字典成员设为值 y

  3. document 为该元素的节点文档

  4. 如果 document 不是活动文档,则终止这些步骤。

  5. windowdocumentdefaultView 属性值。

  6. 如果 window 为 null,则终止这些步骤。

  7. 如果该元素是根元素document 处于怪异模式,则终止这些步骤。

  8. 如果该元素是根元素,则在 window 上调用 scroll(),以 window 上的 scrollX 作为第一个参数,以 y 作为第二个参数,并终止这些步骤。

  9. 如果该元素是body 元素document 处于怪异模式,且该元素不是潜在可滚动的,则在 window 上调用 scroll(),以 options 作为唯一参数,并终止这些步骤。

  10. 如果该元素没有关联的盒模型,或者该元素没有关联的滚动盒模型,或该元素没有溢出,则终止这些步骤。

  11. 滚动该元素x,y,滚动行为为 optionsbehavior 字典成员的值。

scrollTo() 方法被调用时,用户代理必须表现得如同 scroll() 方法以相同的参数被调用一样。

scrollBy() 方法被调用时,用户代理必须执行以下步骤

  1. 如果使用一个参数调用,请遵循以下子步骤:

    1. options 为该参数。

    2. 如果存在,归一化 lefttop 字典成员的非有限值。

  2. 如果使用两个参数调用,请遵循以下子步骤:

    1. options 设为 null,并转换ScrollToOptions 字典。[WEBIDL]

    2. xy 分别为这两个参数。

    3. 归一化 xy 的非有限值。

    4. optionsleft 字典成员设为值 x

    5. optionstop 字典成员设为值 y

  3. scrollLeft 的值加到 left 字典成员中。

  4. scrollTop 的值加到 top 字典成员中。

  5. 表现得如同 scroll() 方法以 options 作为唯一参数被调用一样。

测试

当获取 scrollTop 属性时,必须返回运行以下步骤的结果

  1. document 为该元素的节点文档

  2. 如果 document 不是活动文档,则返回 0 并终止这些步骤。

  3. windowdocumentdefaultView 属性值。

  4. 如果 window 为 null,则返回 0 并终止这些步骤。

  5. 如果该元素是根元素document 处于怪异模式,则返回 0 并终止这些步骤。

  6. 如果该元素是根元素,则返回 windowscrollY 的值。

  7. 如果该元素是body 元素document 处于怪异模式,且该元素不是潜在可滚动的,则返回 windowscrollY 的值。

  8. 如果该元素没有关联的盒模型,则返回 0 并终止这些步骤。

  9. 返回滚动区域与该元素内边距边缘顶部对齐点的 y 坐标。

当设置 scrollTop 属性时,必须执行以下步骤

  1. y 为给定值。

  2. 归一化 y 的非有限值。

  3. document 为该元素的节点文档

  4. 如果 document 不是活动文档,则终止这些步骤。

  5. windowdocumentdefaultView 属性值。

  6. 如果 window 为 null,则终止这些步骤。

  7. 如果该元素是根元素document 处于怪异模式,则终止这些步骤。

  8. 如果该元素是根元素,则在 window 上调用 scroll(),以 window 上的 scrollX 作为第一个参数,以 y 作为第二个参数,并终止这些步骤。

  9. 如果该元素是body 元素document 处于怪异模式,且该元素不是潜在可滚动的,则在 window 上调用 scroll(),以 window 上的 scrollX 作为第一个参数,以 y 作为第二个参数,并终止这些步骤。

  10. 如果该元素没有关联的盒模型,该元素没有关联的滚动盒模型,或该元素没有溢出,则终止这些步骤。

  11. 滚动该元素scrollLeft,y,滚动行为为 "auto"。

测试

当获取 scrollLeft 属性时,必须返回运行以下步骤的结果

  1. document 为该元素的节点文档

  2. 如果 document 不是活动文档,则返回 0 并终止这些步骤。

  3. windowdocumentdefaultView 属性值。

  4. 如果 window 为 null,则返回 0 并终止这些步骤。

  5. 如果该元素是根元素document 处于怪异模式,则返回 0 并终止这些步骤。

  6. 如果该元素是根元素,则返回 windowscrollX 的值。

  7. 如果该元素是body 元素document 处于怪异模式,且该元素不是潜在可滚动的,则返回 windowscrollX 的值。

  8. 如果该元素没有关联的盒模型,则返回 0 并终止这些步骤。

  9. 返回滚动区域与该元素内边距边缘左侧对齐点的 x 坐标。

当设置 scrollLeft 属性时,必须执行以下步骤

  1. x 为给定值。

  2. 归一化 x 的非有限值。

  3. document 为该元素的节点文档

  4. 如果 document 不是活动文档,则终止这些步骤。

  5. windowdocumentdefaultView 属性值。

  6. 如果 window 为 null,则终止这些步骤。

  7. 如果该元素是根元素document 处于怪异模式,则终止这些步骤。

  8. 如果该元素是根元素,则在 window 上调用 scroll(),以 x 作为第一个参数,以 window 上的 scrollY 作为第二个参数,并终止这些步骤。

  9. 如果该元素是body 元素document 处于怪异模式,且该元素不是潜在可滚动的,则在 window 上调用 scroll(),以 x 作为第一个参数,以 window 上的 scrollY 作为第二个参数,并终止这些步骤。

  10. 如果该元素没有关联的盒模型,该元素没有关联的滚动盒模型,或该元素没有溢出,则终止这些步骤。

  11. 滚动该元素x,scrollTop,滚动行为为 "auto"。

测试

当获取 scrollWidth 属性时,必须返回运行以下步骤的结果

  1. document 为该元素的节点文档

  2. 如果 document 不是活动文档,则返回 0 并终止这些步骤。

  3. 视口宽度视口的宽度,不包含滚动条宽度(如果有),或者如果不存在视口,则为 0。

  4. 如果该元素是根元素document 不处于怪异模式,则返回 max(视口 滚动区域宽度, 视口宽度)。

  5. 如果该元素是body 元素document 处于怪异模式,且该元素不是潜在可滚动的,则返回 max(视口 滚动区域宽度, 视口宽度)。

  6. 如果该元素没有关联的盒模型,则返回 0 并终止这些步骤。

  7. 返回该元素滚动区域的宽度。

测试

当获取 scrollHeight 属性时,必须返回运行以下步骤的结果

  1. document 为该元素的节点文档

  2. 如果 document 不是活动文档,则返回 0 并终止这些步骤。

  3. 视口高度视口的高度,不包含滚动条高度(如果有),或者如果不存在视口,则为 0。

  4. 如果该元素是根元素document 不处于怪异模式,则返回 max(视口 滚动区域高度, 视口高度)。

  5. 如果该元素是body 元素document 处于怪异模式,且该元素不是潜在可滚动的,则返回 max(视口 滚动区域高度, 视口高度)。

  6. 如果该元素没有关联的盒模型,则返回 0 并终止这些步骤。

  7. 返回该元素滚动区域的高度。

当获取 clientTop 属性时,必须执行以下步骤

  1. 如果该元素没有关联的盒模型,或者盒模型是内联的,则返回 0。

  2. 返回未缩放border-top-width 属性的计算值,加上在顶部内边距边缘与顶部边框边缘之间渲染的任何滚动条高度,同时忽略应用于该元素及其祖先的任何变换

测试

当获取 clientLeft 属性时,必须执行以下步骤

  1. 如果该元素没有关联的盒模型,或者盒模型是内联的,则返回 0。

  2. 返回未缩放border-left-width 属性的计算值,加上在左侧内边距边缘与左侧边框边缘之间渲染的任何滚动条宽度,同时忽略应用于该元素及其祖先的任何变换

当获取 clientWidth 属性时,必须执行以下步骤

  1. 如果该元素没有关联的盒模型,或者盒模型是内联的,则返回 0。

  2. 如果该元素是根元素且该元素的节点文档不处于怪异模式,或者该元素是body 元素且该元素的节点文档确实处于怪异模式,则返回视口宽度(排除渲染的滚动条大小,如果有)。

  3. 返回未缩放内边距边缘宽度,排除在内边距边缘边框边缘之间渲染的任何滚动条宽度,同时忽略应用于该元素及其祖先的任何变换

当获取 clientHeight 属性时,必须执行以下步骤

  1. 如果该元素没有关联的盒模型,或者盒模型是内联的,则返回 0。

  2. 如果该元素是根元素且该元素的节点文档不处于怪异模式,或者该元素是body 元素且该元素的节点文档确实处于怪异模式,则返回视口高度(排除渲染的滚动条大小,如果有)。

  3. 返回未缩放内边距边缘高度,排除在内边距边缘边框边缘之间渲染的任何滚动条高度,同时忽略应用于该元素及其祖先的任何变换

当获取 currentCSSZoom 属性时,必须返回该元素的有效缩放比例;如果该元素未被渲染,则返回 1.0。

测试

6.1. Element 滚动成员

要为元素伪元素范围(即目标 target确定滚动到视图中的位置,其中包含滚动行为 behavior、块流方向位置 block、内联基准方向位置 inline 以及一个滚动盒模型 scrolling box,需运行以下步骤

  1. target bounding border box 为调用元素 getBoundingClientRect() 的返回值所表示的盒模型(如果 target 是一个元素),或者为范围 getBoundingClientRect() 的返回值(如果 target 是一个范围)。

  2. scrolling box edge Ascrolling box块流方向上的起始边缘,令 element edge Atarget bounding border boxscrolling box edge A 在同一物理侧的边缘。

  3. scrolling box edge Bscrolling box块流方向上的结束边缘,令 element edge Btarget bounding border boxscrolling box edge B 在同一物理侧的边缘。

  4. scrolling box edge Cscrolling box内联基准方向上的起始边缘,令 element edge Ctarget bounding border boxscrolling box edge C 在同一物理侧的边缘。

  5. scrolling box edge Dscrolling box内联基准方向上的结束边缘,令 element edge Dtarget bounding border boxscrolling box edge D 在同一物理侧的边缘。

  6. element heightelement edge Aelement edge B 之间的距离。

  7. scrolling box heightscrolling box edge Ascrolling box edge B 之间的距离。

  8. element widthelement edge Celement edge D 之间的距离。

  9. scrolling box widthscrolling box edge Cscrolling box edge D 之间的距离。

  10. positionscrolling box 通过执行这些步骤所能达到的滚动位置

    1. 如果 block 为 "start",则将 element edge Ascrolling box edge A 对齐。

    2. 否则,如果 block 为 "end",则将 element edge Bscrolling box edge B 对齐。

    3. 否则,如果 block 为 "center",则在 scrolling box块流方向上,将 target bounding border box 的中心与 scrolling box 的中心对齐。

    4. 否则,block 为 "nearest"

      如果 element edge Aelement edge B 均位于 scrolling box edge Ascrolling box edge B 之外
      不执行任何操作。
      如果 element edge A 位于 scrolling box edge A 之外且 element height 小于 scrolling box height
      如果 element edge B 位于 scrolling box edge B 之外且 element height 大于 scrolling box height
      element edge Ascrolling box edge A 对齐。
      如果 element edge A 位于 scrolling box edge A 之外且 element height 大于 scrolling box height
      如果 element edge B 位于 scrolling box edge B 之外且 element height 小于 scrolling box height
      element edge Bscrolling box edge B 对齐。
    5. 如果 inline 为 "start",则将 element edge Cscrolling box edge C 对齐。

    6. 否则,如果 inline 为 "end",则将 element edge Dscrolling box edge D 对齐。

    7. 否则,如果 inline 为 "center",则在 scrolling box内联基准方向上,将 target bounding border box 的中心与 scrolling box 的中心对齐。

    8. 否则,inline 为 "nearest"

      如果 element edge Celement edge D 均位于 scrolling box edge Cscrolling box edge D 之外
      不执行任何操作。
      如果 element edge C 位于 scrolling box edge C 之外且 element width 小于 scrolling box width
      如果 element edge D 位于 scrolling box edge D 之外且 element width 大于 scrolling box width
      element edge Cscrolling box edge C 对齐。
      如果 element edge C 位于 scrolling box edge C 之外且 element width 大于 scrolling box width
      如果 element edge D 位于 scrolling box edge D 之外且 element width 小于 scrolling box width
      element edge Dscrolling box edge D 对齐。
    9. 如果 target 是一个元素,且目标元素定义了一些滚动捕捉位置,那么当其最近的滚动容器是一个滚动捕捉容器时,用户代理必须将所得的 position 滚动捕捉到该元素的其中一个滚动捕捉位置。即使在滚动容器具有 scroll-snap-type: none 时,用户代理也可以这样做。

    10. 返回 position

将目标滚动到视图中,即目标 target(为一个元素伪元素范围),伴随滚动行为 behavior、块流方向位置 block、内联基准方向位置 inline 以及一个可选的包含元素 container 以在到达该容器后停止滚动,意味着执行以下步骤
  • 按照从最内层到最外层滚动盒模型的顺序,对于每个建立滚动盒模型 scrolling box 的祖先元素或视口,运行以下子步骤

    1. 如果与 target 关联的 Document 与与该元素或与 scrolling box 关联的视口关联的 Document 不是同源的,则终止这些步骤。

    2. position 为通过运行确定滚动到视图中的位置的步骤所得到的滚动位置,其中使用 behavior 作为 滚动行为block 作为 块流位置inline 作为 内联基准方向位置,以及 scrolling box 作为 滚动盒模型

    3. 如果 positionscrolling box 当前的滚动位置不相同,或者 scrolling box 正在进行平滑滚动

      1. 如果 scrolling box 与某个元素关联
        执行该元素滚动盒模型的滚动position,以该元素作为关联元素,并以 behavior 作为滚动行为。
        如果 scrolling box 与某个视口关联
        1. document视口关联的 Document

        2. root elementdocument根元素(如果有),否则为 null。

        3. 执行视口的滚动position,以 root element 作为关联元素,并以 behavior 作为滚动行为。

    4. 如果 container 不为 null,且 scrolling box 或者是 container包含阴影树的包含祖先,或者是其文档container包含阴影树的包含祖先视口,则中止剩余步骤。

  • 滚动元素(或伪元素elementx,y,并可选地伴随滚动行为 behavior(如果省略则为 "auto"),意味着要

    1. boxelement 关联的滚动盒模型

    2. 如果 box 具有向右的溢出方向
      x 为 max(0, min(x, element 滚动区域宽度 - element 内边距边缘宽度))。
      如果 box 具有向左的溢出方向
      x 为 min(0, max(x, element 内边距边缘宽度 - element 滚动区域宽度))。
    3. 如果 box 具有向下的溢出方向
      y 为 max(0, min(y, element 滚动区域高度 - element 内边距边缘高度))。
      如果 box 具有向上的溢出方向
      y 为 min(0, max(y, element 内边距边缘高度 - element 滚动区域高度))。
    4. positionbox 通过将滚动区域的 x 坐标 xbox 的左侧对齐,并将滚动区域的 y 坐标 ybox 的顶部对齐所能达到的滚动位置。

    5. 如果 positionbox 当前的滚动位置相同,且 box 没有进行中的平滑滚动,则中止这些步骤。

    6. 执行 box 的滚动position,以 element 作为关联元素,并以 behavior 作为滚动行为。

    7. HTMLElement 接口扩展

    partial interface HTMLElement {
      readonly attribute Element? scrollParent;
      readonly attribute Element? offsetParent;
      readonly attribute long offsetTop;
      readonly attribute long offsetLeft;
      readonly attribute long offsetWidth;
      readonly attribute long offsetHeight;
    };
    

    当获取 scrollParent 属性时,必须返回运行以下步骤的结果

    1. 如果以下任意条件为真,则返回 null 并终止此算法

    2. ancestor 为该元素在扁平树中的包含块,并重复这些子步骤

      1. 如果 ancestor初始包含块,若该元素的文档的 scrollingElement 对该元素而言不是封闭阴影隐藏的,则返回该元素文档的 scrollingElement,否则返回 null。

      2. 如果 ancestor 对该元素而言不是封闭阴影隐藏的,且是一个滚动容器,则终止此算法并返回 ancestor

      3. 如果 ancestorposition 属性的计算值为 fixed,且没有任何祖先元素建立固定定位的 包含块(containing block),则终止此算法并返回 null。

      4. ancestorancestor平铺树(flat tree) 中的 包含块

    测试

    offsetParent 属性必须返回运行这些步骤的结果。

    1. 如果满足以下任一条件,则返回 null 并终止此算法:

    2. ancestor 为该元素在 平铺树 中的父级,并重复这些子步骤:

      1. 如果 ancestor 对于该元素来说是 闭合阴影隐藏(closed-shadow-hidden) 的,且其 position 属性计算值为 fixed,且没有任何祖先元素建立固定定位的 包含块,则终止此算法并返回 null。

      2. 如果 ancestor 对于该元素来说不是 闭合阴影隐藏 的,并且满足以下至少一项条件,则终止此算法并返回 ancestor

        • 该元素位于固定定位的 包含块 中,且 ancestor 是固定定位后代元素的包含块。

        • 该元素不在固定定位的 包含块 中,并且:

          • ancestor 是绝对定位后代元素的包含块(无论是否存在任何绝对定位的后代)。

          • 它是 body 元素

          • 该元素的 position 属性计算值为 static,且该祖先元素是以下 HTML 元素 之一:tdthtable

        • 该元素具有与 ancestor 不同的 有效缩放(effective zoom)

      3. 如果 ancestor平铺树 中没有更多父级,则终止此算法并返回 null。

      4. ancestorancestor平铺树 中的父级。

    测试

    offsetTop 属性必须返回运行这些步骤的结果。

    1. 如果该元素是 body 元素 或没有任何关联的 盒子,则返回 0 并终止此算法。

    2. 如果该元素的 offsetParent 为 null,则返回该元素关联的第一个 盒子 的顶部 边框边缘(border edge) 相对于 初始包含块 原点的 未缩放 y 坐标,忽略应用于该元素及其祖先的任何 变换(transforms),并终止此算法。

    3. 返回该元素关联的第一个 盒子 的顶部 边框边缘 y 坐标,减去该元素的 offsetParent 关联的第一个 盒子 的顶部 内边距边缘(padding edge) y 坐标的 未缩放 结果(相对于 初始包含块 原点),忽略应用于该元素及其祖先的任何 变换

      注意:由多个行框组成的行内元素,只会考虑其第一个 盒子

    测试

    offsetLeft 属性必须返回运行这些步骤的结果。

    1. 如果该元素是 body 元素 或没有任何关联的 盒子,则返回 0 并终止此算法。

    2. 如果该元素的 offsetParent 为 null,则返回该元素关联的第一个 盒子 的左侧 边框边缘 相对于 初始包含块 原点的 未缩放 x 坐标,忽略应用于该元素及其祖先的任何 变换,并终止此算法。

    3. 返回该元素关联的第一个 盒子 的左侧 边框边缘 x 坐标,减去该元素的 offsetParent 关联的第一个 盒子 的左侧 内边距边缘 x 坐标的 未缩放 结果(相对于 初始包含块 原点),忽略应用于该元素及其祖先的任何 变换

    offsetWidth 属性必须返回运行这些步骤的结果。

    1. 如果该元素没有任何关联的 盒子,则返回 0 并终止此算法。

    2. 返回该元素 主体盒子(principal box) 生成的所有片段的 边框盒子(border boxes) 的轴对齐外接矩形的 未缩放 宽度,忽略应用于该元素及其祖先的任何 变换

      如果该元素的 主体盒子 是被 块级(block-level) 后代“分割”的 行内级盒子,则还应包含该 块级 后代生成的片段,除非它们的宽度或高度为零。

    测试

    offsetHeight 属性必须返回运行这些步骤的结果。

    1. 如果该元素没有任何关联的 盒子,则返回 0 并终止此算法。

    2. 返回该元素 主体盒子 生成的所有片段的 边框盒子 的轴对齐外接矩形的 未缩放 高度,忽略应用于该元素及其祖先的任何 变换

      如果该元素的 主体盒子 是被 块级 后代“分割”的 行内级盒子,则还应包含该 块级 后代生成的片段,除非它们的宽度或高度为零。

    8. HTMLImageElement 接口的扩展

    partial interface HTMLImageElement {
      readonly attribute long x;
      readonly attribute long y;
    };
    

    x 属性在获取时,必须返回该元素关联的第一个 盒子 的左侧 边框边缘 相对于 初始包含块 原点的 已缩放 x 坐标,忽略应用于该元素及其祖先的任何 变换;如果没有 盒子,则返回 0。

    y 属性在获取时,必须返回该元素关联的第一个 盒子 的顶部 边框边缘 相对于 初始包含块 原点的 已缩放 y 坐标,忽略应用于该元素及其祖先的任何 变换;如果没有 盒子,则返回 0。

    测试

    9. Range 接口的扩展

    partial interface Range {
      DOMRectList getClientRects();
      [NewObject] DOMRect getBoundingClientRect();
    };
    

    getClientRects() 方法在调用时,如果该范围不在文档中,则必须返回一个空的 DOMRectList 对象,否则返回一个 DOMRectList 对象,其中包含按内容顺序排列并符合以下约束的 DOMRect 对象列表:

    注意:getClientRects() 返回的 DOMRect 对象不是 实时的(live)

    测试

    getBoundingClientRect() 方法在调用时,必须返回以下算法的结果。

    1. list 为在该方法被调用的同一范围上调用 getClientRects() 的结果。

    2. 如果 list 为空,则返回一个 DOMRect 对象,其 xywidthheight 成员均为 0。

    3. 如果 list 中的所有矩形宽度或高度均为 0,则返回 list 中的第一个矩形。

    4. 否则,返回一个 DOMRect 对象,描述包含 list 中所有高度或宽度不为 0 的矩形的最小矩形。

    注意:getBoundingClientRect() 返回的 DOMRect 对象不是 实时的

    测试

    10. MouseEvent 接口的扩展

    对象 IDL 片段重定义了一些成员。我们能以某种方式解决这个问题吗?

    partial interface MouseEvent {
      readonly attribute double screenX;
      readonly attribute double screenY;
      readonly attribute double pageX;
      readonly attribute double pageY;
      readonly attribute double clientX;
      readonly attribute double clientY;
      readonly attribute double x;
      readonly attribute double y;
      readonly attribute double offsetX;
      readonly attribute double offsetY;
    };
    
    partial dictionary MouseEventInit {
      double screenX = 0.0;
      double screenY = 0.0;
      double clientX = 0.0;
      double clientY = 0.0;
    };
    
    测试

    screenX 属性必须返回事件发生位置相对于 Web 公开屏幕区域 原点的 x 坐标。

    screenY 属性必须返回事件发生位置相对于 Web 公开屏幕区域 原点的 y 坐标。

    pageX 属性必须遵循以下步骤:

    1. 如果事件的 分发标志(dispatch flag) 已设置,则返回事件发生位置相对于 初始包含块 原点的水平坐标,并终止这些步骤。

    2. offset 为事件关联的 Window 对象的 scrollX 属性值(如果有),否则为 0。

    3. 返回 offset 与事件 clientX 属性值的总和。

    pageY 属性必须遵循以下步骤:

    1. 如果事件的 分发标志 已设置,则返回事件发生位置相对于 初始包含块 原点的垂直坐标,并终止这些步骤。

    2. offset 为事件关联的 Window 对象的 scrollY 属性值(如果有),否则为 0。

    3. 返回 offset 与事件 clientY 属性值的总和。

    clientX 属性必须返回事件发生位置相对于 视口(viewport) 原点的 x 坐标。

    clientY 属性必须返回事件发生位置相对于 视口 原点的 y 坐标。

    x 属性必须返回 clientX 的值。

    y 属性必须返回 clientY 的值。

    offsetX 属性必须遵循以下步骤:

    1. 如果事件的 分发标志 已设置,则返回事件发生位置相对于目标节点 内边距边缘 原点的 x 坐标,忽略应用于该元素及其祖先的 变换,并终止这些步骤。

    2. 返回事件 pageX 属性的值。

    测试

    offsetY 属性必须遵循以下步骤:

    1. 如果事件的 分发标志 已设置,则返回事件发生位置相对于目标节点 内边距边缘 原点的 y 坐标,忽略应用于该元素及其祖先的 变换,并终止这些步骤。

    2. 返回事件 pageY 属性的值。

    11. 几何

    11.1. GeometryUtils 接口

    enum CSSBoxType { "margin", "border", "padding", "content" };
    dictionary BoxQuadOptions {
      CSSBoxType box = "border";
      GeometryNode relativeTo; // XXX default document (i.e. viewport)
    };
    
    dictionary ConvertCoordinateOptions {
      CSSBoxType fromBox = "border";
      CSSBoxType toBox = "border";
    };
    
    interface mixin GeometryUtils {
      sequence<DOMQuad> getBoxQuads(optional BoxQuadOptions options = {});
      DOMQuad convertQuadFromNode(DOMQuadInit quad, GeometryNode from, optional ConvertCoordinateOptions options = {});
      DOMQuad convertRectFromNode(DOMRectReadOnly rect, GeometryNode from, optional ConvertCoordinateOptions options = {});
      DOMPoint convertPointFromNode(DOMPointInit point, GeometryNode from, optional ConvertCoordinateOptions options = {}); // XXX z,w turns into 0
    };
    
    Text includes GeometryUtils; // like Range
    Element includes GeometryUtils;
    CSSPseudoElement includes GeometryUtils;
    Document includes GeometryUtils;
    
    typedef (Text or Element or CSSPseudoElement or Document) GeometryNode;
    

    getBoxQuads(options) 方法必须运行以下步骤:

    1. DOM 顺序

      p1 = 左上角,即使在 RTL 中也是如此

      缩放为 0 表示除以零,返回 0x0

      不允许跨框架,抛出 WrongDocumentError?

      点被平坦化(3D 变换),z=0,类似于 getClientRect

      测试块级元素在行内元素中

      伪元素 before/after 是元素的子级

      视口盒子都是一样的

    测试

    convertQuadFromNode(quad, from, options) 方法必须运行以下步骤:

    1. ...

    convertRectFromNode(rect, from, options) 方法必须运行以下步骤:

    1. ...

    convertPointFromNode(point, from, options) 方法必须运行以下步骤:

    1. ...

    12. VisualViewport

    12.1. VisualViewport 接口

    [Exposed=Window]
    interface VisualViewport : EventTarget {
      readonly attribute double offsetLeft;
      readonly attribute double offsetTop;
    
      readonly attribute double pageLeft;
      readonly attribute double pageTop;
    
      readonly attribute double width;
      readonly attribute double height;
    
      readonly attribute double scale;
    
      attribute EventHandler onresize;
      attribute EventHandler onscroll;
      attribute EventHandler onscrollend;
    };
    

    offsetLeft 属性必须运行这些步骤:

    1. 如果 视觉视口(visual viewport)关联文档 不是 完全活动(fully active) 的,则返回 0。

    2. 否则,返回 视觉视口 左边缘相对于 布局视口(layout viewport) 左边缘的偏移量。

    offsetTop 属性必须运行这些步骤:

    1. 如果 视觉视口关联文档 不是 完全活动 的,则返回 0。

    2. 否则,返回 视觉视口 顶边缘相对于 布局视口 顶边缘的偏移量。

    pageLeft 属性必须运行这些步骤:

    1. 如果 视觉视口关联文档 不是 完全活动 的,则返回 0。

    2. 否则,返回 视觉视口 左边缘相对于 布局视口文档初始包含块 左边缘的偏移量。

    pageTop 属性必须运行这些步骤:

    1. 如果 视觉视口关联文档 不是 完全活动 的,则返回 0。

    2. 否则,返回 视觉视口 顶边缘相对于 布局视口文档初始包含块 顶边缘的偏移量。

    width 属性必须运行这些步骤:

    1. 如果 视觉视口关联文档 不是 完全活动 的,则返回 0。

    2. 否则,返回 视觉视口 的宽度,减去任何固定在视觉视口上的已渲染垂直 经典滚动条(classic scrollbar) 的宽度。

    注意:由于此值是以 CSS 像素返回的,因此如果增加 页面缩放(page zoom)缩放因子(scale factor),该值的大小将会减小。

    注意:固定在视觉视口上的滚动条是指在缩放和平移视觉视口时不会改变大小或位置的滚动条。由于此值是以 CSS 像素为单位的,因此在排除滚动条宽度时,UA 必须考虑滚动条在 CSS 像素中的大小。也就是说,当放大时,排除的数量会减少;当缩小时,排除的数量会增加。

    height 属性必须运行这些步骤:

    1. 如果 视觉视口关联文档 不是 完全活动 的,则返回 0。

    2. 否则,返回 视觉视口 的高度,减去任何固定在视觉视口上的已渲染水平 经典滚动条 的高度。

    scale 属性必须运行这些步骤:

    1. 如果 视觉视口关联文档 不是 完全活动 的,则返回 0 并终止这些步骤。

    2. 如果没有输出设备,则返回 1 并中止这些步骤。

    3. 否则,返回 视觉视口缩放因子

    onresizeresize 事件的 事件处理程序 IDL 属性

    onscrollscroll 事件的 事件处理程序 IDL 属性

    onscrollendscrollend 事件的 事件处理程序 IDL 属性

    13. 事件

    13.1. 调整视口大小

    本节与 HTML 中定义的 事件循环(event loop) 集成。 [HTML]

    当被要求为 Document doc 运行调整大小步骤(run the resize steps) 时,运行以下步骤:

    1. 如果 doc视口 自上次运行这些步骤以来,其宽度或高度发生了变化(例如由于用户调整了浏览器窗口,或更改了 页面缩放,或 iframe 元素的尺寸发生了变化),则在与 doc 关联的 Window 对象上 触发(fire) 一个名为 resize 的事件。

    2. 如果与 doc 关联的 VisualViewportscalewidthheight 属性自上次运行这些步骤以来发生了变化,则在 VisualViewport触发 一个名为 resize 的事件。

    测试

    13.2. 滚动

    本节与 HTML 中定义的 事件循环 集成。 [HTML]

    每个 Document 都有一个关联的 待处理滚动事件目标列表(pending scroll event targets),最初为空。

    每个 Document 都有一个关联的 待处理 scrollend 事件目标列表,最初为空。

    每当 视口 发生滚动(无论是响应用户交互还是通过 API),用户代理都必须运行以下步骤:

    1. doc视口 的关联 Document

    2. 如果 doc 是一个 滚动捕捉容器(snap container),则运行 更新 scrollsnapchanging 目标 的步骤,其中 doc 在块轴方向的 最终捕捉目标 为 newBlockTarget,doc 在内联轴方向的 最终捕捉目标 为 newInlineTarget。

    3. 如果 doc 已经在 doc待处理滚动事件目标列表 中,则终止这些步骤。

    4. doc 添加到 doc待处理滚动事件目标列表 中。

    每当元素发生滚动(无论是响应用户交互还是通过 API),用户代理都必须运行以下步骤:

    1. doc 为该元素的 节点文档(node document)

    2. 如果该元素是 滚动捕捉容器,则运行 更新 scrollsnapchanging 目标 的步骤,其中该元素在块轴方向的 最终捕捉目标 为 newBlockTarget,该元素在内联轴方向的 最终捕捉目标 为 newInlineTarget。

    3. 如果该元素已经在 doc待处理滚动事件目标列表 中,则终止这些步骤。

    4. 将该元素添加到 doc待处理滚动事件目标列表 中。

    每当 视觉视口 发生滚动(无论是响应用户交互还是通过 API),用户代理都必须运行以下步骤:

    1. vv 为滚动的 VisualViewport 对象。

    2. docvv关联文档

    3. 如果 vv 已经在 doc待处理滚动事件目标列表 中,则终止这些步骤。

    4. vv 添加到 doc待处理滚动事件目标列表 中。

    当被要求为 Document doc 运行滚动步骤(run the scroll steps) 时,运行以下步骤:

    1. 运行为 doc 分发待处理 scrollsnapchanging 事件 的步骤。

    2. 对于 doc待处理滚动事件目标列表 中的每个项目 target,按添加到列表的顺序,运行以下子步骤:

      1. 如果 targetDocument,则在 target触发 一个冒泡的名为 scroll 的事件。

      2. 否则,在 target触发 一个名为 scroll 的事件。

    3. 清空 doc待处理滚动事件目标列表

    4. 运行为 doc 分发待处理 scrollsnapchange 事件 的步骤。

    每当滚动 完成(completed) 时,用户代理必须运行以下步骤:

    scrollend 事件的触发顺序是什么?是基于滚动开始还是滚动完成?

    1. 对于每个已滚动的滚动盒子 box

      1. 如果 box 属于一个 视口,令 doc视口 的关联 Documenttarget 为该 视口。如果 box 属于一个 VisualViewport,令 docVisualViewport关联文档target 为该 VisualViewport。否则,box 属于一个元素,令 doc 为该元素的 节点文档target 为该元素。

      2. 如果 box 属于一个 滚动捕捉容器 snapcontainer,则运行 snapcontainer更新 scrollsnapchange 目标 步骤。

      3. 如果 target 已经在 doc待处理 scrollend 事件目标列表 中,则终止这些步骤。

      4. target 添加到 doc待处理 scrollend 事件目标列表 中。

    2. 运行为 doc 分发待处理 scrollsnapchange 目标 的步骤。

    3. 对于 doc待处理 scrollend 事件目标列表 中的每个项目 target,按添加到列表的顺序,运行以下子步骤:

      1. 如果 targetDocument,则在 target触发 一个冒泡的名为 scrollend 的事件。

      2. 否则,在 target触发 一个名为 scrollend 的事件。

    4. 清空 doc待处理 scrollend 事件目标列表

    13.3. 事件摘要

    本节是非规范性的。

    EventInterface感兴趣的目标描述
    resize Event Window, VisualViewport视口 大小调整时,在 Window 上触发。当 视觉视口 大小调整或 布局视口 被缩放时,在 VisualViewport 上触发。
    scroll Event VisualViewport, Document, 元素VisualViewport视口 或元素分别发生滚动时,分别在 VisualViewportDocument 或元素上触发。
    scrollend Event Document, 元素, VisualViewport当滚动 完成 时,在 VisualViewportDocument 或元素上触发:VisualViewport视口 或元素已滚动,滚动序列已结束,并且任何滚动偏移量的更改均已应用。

    14. 布局后状态快照

    一些 CSS 特性使用布局后的状态(如滚动位置)作为下一次样式和布局更新的输入。

    当被要求为 Document doc 运行快照布局后状态步骤(run snapshot post-layout state steps) 时,运行以下步骤:

    1. 对于每个需要对布局后状态进行快照的 CSS 特性,拍摄 doc 中相关状态的快照。

    拍摄快照的状态在其他规范中定义。这些步骤绝不能以其他布局后快照步骤能够观察到该快照发生的方式使 doc 或任何其他 Document 失效。因此,此类快照进行的顺序必须无关紧要。

    15. 隐私考量

    Screen 接口公开了有关用户显示配置的信息,这些信息可能被用作指纹算法的输入。用户代理可以选择隐藏或量化有关屏幕大小或配置的信息,以保护用户的隐私。

    MouseEvent 包含有关事件相对于屏幕的坐标信息。用户代理可以将这些属性设置为掩盖事件实际屏幕相对位置的值,以保护用户的隐私。

    16. 安全考量

    本规范未报告任何新的安全考量。

    17. 变更

    本节记录了本规范各个版本之间的一些变更。本节并不详尽。错误修复和编辑性更改通常不会列出。

    2016 年 3 月 17 日工作草案以来的变更

    2013 年 12 月 17 日工作草案以来的变更

    2011 年 8 月 4 日工作草案以来的变更

    2009 年 8 月 4 日工作草案以来的变更

    2008 年 2 月 22 日工作草案以来的变更

    18. 致谢

    编辑们衷心感谢 Alan Stearns, Alexey Feldgendler, Antonio Gomes, Björn Höhrmann, Boris Zbarsky, Chris Rebert, Corey Farwell, Dan Bates, David Vest, Elliott Sprehn, Garrett Smith, Henrik Andersson, Hallvord R. M. Steen, Kang-Hao Lu, Koji Ishii, Leif Arne Storset, Luiz Agostini, Maciej Stachowiak, Michael Dyck, Mike Wilson, Morten Stenshorne, Olli Pettay, Pavel Curtis, Peter-Paul Koch, Rachel Kmetz, Rick Byers, Robert O’Callahan, Sam Weinig, Scott Johnson, Sebastian Zartner, Stewart Brodie, Sylvain Galineau, Tab Atkins, Tarquin Wilton-Jones, Thomas Moore, Thomas Shinnick 以及 Xiaomei Ji 对本文档所作的贡献。

    特别感谢首先实现本草案中列出的许多功能并由 Windows Internet Explorer 浏览器广泛部署的微软员工。

    一致性

    文档约定

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

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

    本规范中的示例均以“例如”一词引入,或者通过 class="example" 与规范性文本隔开,如下所示

    这是一个说明性示例。

    说明性注释以“Note”一词开头,并使用 class="note" 与规范性文本隔开,如下所示

    注意,这是一个说明性注释。

    建议(Advisements)是规范性章节,旨在引起特别注意,并使用 <strong class="advisement"> 与其他规范性文本区分开来,如下所示: 用户代理必须提供可访问的替代方案。

    测试

    与本规范内容相关的测试可记录在“Tests”块中,就像这一个一样。任何此类块都是非规范性的。


    一致性类别

    本规范为三类一致性定义了一致性要求。

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

    如果样式表包含的所有使用本模块定义语法的语句,根据通用 CSS 语法及本模块定义的各功能语法均有效,则该样式表符合本规范。

    如果渲染器除了按相应规范解释样式表外,还通过正确解析本规范定义的所有功能并相应地渲染文档来支持这些功能,则该渲染器符合本规范。然而,由于设备限制导致 UA 无法正确渲染文档,并不意味着该 UA 不符合规范。(例如,UA 无需在单色显示器上渲染颜色。)

    如果创作工具编写的样式表根据通用 CSS 语法及本模块中各功能的语法是句法正确的,并符合本模块中描述的所有其他样式表一致性要求,则该创作工具符合本规范。

    部分实现

    为了使作者能够利用前向兼容的解析规则来指定后备值,CSS 渲染器 **必须** 将其无法使用支持级别的任何 @规则、属性、属性值、关键字和其他语法结构视为无效(并 适当忽略)。特别地,用户代理 **不得** 在单一多值属性声明中选择性地忽略不支持的组件值而保留支持的值:如果任何值被视为无效(因为不支持的值必须如此),CSS 要求忽略整个声明。

    不稳定和专有特性的实现

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

    非实验性实现

    一旦规范达到候选推荐阶段,非实验性实现即可成为可能,实现者应发布他们能够证明根据规范正确实现的任何 CR 级别特性的无前缀实现。

    为建立并保持 CSS 在不同实现间的互操作性,CSS 工作组请求非实验性的 CSS 渲染器在发布任何 CSS 功能的无前缀实现之前,向 W3C 提交一份实现报告(并在必要时提交用于该实现报告的测试用例)。提交给 W3C 的测试用例需经 CSS 工作组审阅和修正。

    有关提交测试用例和实现报告的详细信息,请访问 CSS 工作组网站 https://w3org.cn/Style/CSS/Test/。问题可发送至 public-css-testsuite@w3.org 邮件列表。

    索引

    本规范定义的术语

    通过引用定义的术语

    引用

    规范性引用

    [CSS-ALIGN-3]
    Elika Etemad; Tab Atkins Jr.. CSS 盒子对齐模块 Level 3. 2025 年 3 月 11 日. 工作草案 (WD). URL: https://w3org.cn/TR/css-align-3/
    [CSS-BACKGROUNDS-3]
    Elika Etemad; Brad Kemper. CSS 背景与边框模块 3 级 (CSS Backgrounds and Borders Module Level 3). 2024年3月11日. CRD. URL: https://w3org.cn/TR/css-backgrounds-3/
    [CSS-BORDERS-4]
    Elika Etemad; et al. CSS 边框与盒装饰模块 Level 4. 2025 年 7 月 22 日. FPWD. URL: https://w3org.cn/TR/css-borders-4/
    [CSS-BOX-4]
    Elika Etemad. CSS 盒模型模块 Level 4. 2024 年 8 月 4 日. WD. URL: https://w3org.cn/TR/css-box-4/
    [CSS-BREAK-4]
    Rossen Atanassov; Elika Etemad. CSS 分片模块 Level 4. 2018 年 12 月 18 日. FPWD. URL: https://w3org.cn/TR/css-break-4/
    [CSS-COLOR-4]
    Chris Lilley; Tab Atkins Jr.; Lea Verou. CSS 颜色模块 Level 4. 2025 年 4 月 24 日. CRD. URL: https://w3org.cn/TR/css-color-4/
    [CSS-CONTAIN-2]
    Tab Atkins Jr.; Florian Rivoal; Vladimir Levin. CSS Containment Module Level 2. 2022年9月17日. WD. URL: https://w3org.cn/TR/css-contain-2/
    [CSS-DEVICE-ADAPT]
    Florian Rivoal; Emilio Cobos Álvarez. CSS 视口模块 Level 1. 2024 年 1 月 25 日. FPWD. URL: https://w3org.cn/TR/css-viewport-1/
    [CSS-DISPLAY-4]
    Elika Etemad; Tab Atkins Jr.. CSS 显示模块 Level 4. 2024 年 12 月 19 日. FPWD. URL: https://w3org.cn/TR/css-display-4/
    [CSS-OVERFLOW-3]
    Elika Etemad; Florian Rivoal. CSS Overflow Module Level 3. 2023年3月29日. WD. URL: https://w3org.cn/TR/css-overflow-3/
    [CSS-POSITION-3]
    Elika Etemad; Tab Atkins Jr.. CSS 定位布局模块 Level 3. 2025 年 3 月 11 日. WD. URL: https://w3org.cn/TR/css-position-3/
    [CSS-PSEUDO-4]
    Elika Etemad; Alan Stearns. CSS 伪元素模块 Level 4. 2025 年 6 月 27 日. WD. URL: https://w3org.cn/TR/css-pseudo-4/
    [CSS-SCOPING-1]
    Tab Atkins Jr.; Elika Etemad. CSS 作用域模块 Level 1. 2014 年 4 月 3 日. FPWD. URL: https://w3org.cn/TR/css-scoping-1/
    [CSS-SCROLL-SNAP-1]
    Matt Rakow; et al. CSS Scroll Snap Module Level 1. 2021年3月11日. CR. URL: https://w3org.cn/TR/css-scroll-snap-1/
    [CSS-SCROLL-SNAP-2]
    Elika Etemad; Tab Atkins Jr.; Adam Argyle. CSS 滚动捕捉模块 Level 2. 2024 年 7 月 23 日. FPWD. URL: https://w3org.cn/TR/css-scroll-snap-2/
    [CSS-TEXT-3]
    Elika Etemad; Koji Ishii; Florian Rivoal. CSS 文本模块 Level 3. 2024 年 9 月 30 日. CRD. URL: https://w3org.cn/TR/css-text-3/
    [CSS-TEXT-4]
    Elika Etemad; 等. CSS 文本模块 Level 4. 2024 年 5 月 29 日. WD. URL: https://w3org.cn/TR/css-text-4/
    [CSS-TRANSFORMS-1]
    Simon Fraser; et al. CSS Transforms Module Level 1. 2019年2月14日. CR. URL: https://w3org.cn/TR/css-transforms-1/
    [CSS-VALUES]
    Tab Atkins Jr.; Elika Etemad. CSS 值与单位模块 3 级 (CSS Values and Units Module Level 3). 2024年3月22日. CRD. URL: https://w3org.cn/TR/css-values-3/
    [CSS-VALUES-4]
    Tab Atkins Jr.; Elika Etemad. CSS 值与单位模块 4 级 (CSS Values and Units Module Level 4). 2024年3月12日. WD. URL: https://w3org.cn/TR/css-values-4/
    [CSS-WRITING-MODES-4]
    Elika Etemad; Koji Ishii. CSS Writing Modes Level 4. 2019年7月30日. CR. URL: https://w3org.cn/TR/css-writing-modes-4/
    [CSS2]
    Bert Bos; et al. 层叠样式表 2 级修订版 1 (CSS 2.1) 规范 (Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification). 2011年6月7日. REC. URL: https://w3org.cn/TR/CSS2/
    [CSSOM]
    Daniel Glazman; Emilio Cobos Álvarez. CSS Object Model (CSSOM). 2021年8月26日. WD. URL: https://w3org.cn/TR/cssom-1/
    [CSSOM-VIEW-1]
    Simon Pieters. CSSOM 视图模块. 2016 年 3 月 17 日. WD. URL: https://w3org.cn/TR/cssom-view-1/
    [DOM]
    Anne van Kesteren. DOM 标准. Living Standard. URL: https://dom.spec.whatwg.org/
    [GEOMETRY-1]
    Simon Pieters; Chris Harrelson. Geometry Interfaces Module Level 1. 2018年12月4日. CR. URL: https://w3org.cn/TR/geometry-1/
    [HTML]
    Anne van Kesteren; et al. HTML 标准. Living Standard. URL: https://html.whatwg.cn/multipage/
    [INFRA]
    Anne van Kesteren; Domenic Denicola. Infra 标准. Living Standard. URL: https://infra.spec.whatwg.org/
    [MEDIAQUERIES-5]
    Dean Jackson; 等人. Media Queries Level 5. 2021年12月18日. WD. URL: https://w3org.cn/TR/mediaqueries-5/
    [RFC2119]
    S. Bradner. RFC 中用于指示要求级别的关键词. 1997年3月. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
    [SELECTORS-4]
    Elika Etemad; Tab Atkins Jr.. 选择器第 4 级. 2022 年 11 月 11 日. WD. URL: https://w3org.cn/TR/selectors-4/
    [SVG11]
    Erik Dahlström; et al. 可缩放矢量图形 (SVG) 1.1 (第二版). 2011 年 8 月 16 日. REC. URL: https://w3org.cn/TR/SVG11/
    [SVG2]
    Amelia Bellamy-Royds; et al. Scalable Vector Graphics (SVG) 2. 2018年10月4日. CR. URL: https://w3org.cn/TR/SVG2/
    [UIEVENTS]
    Gary Kacmarcik; Travis Leithead. UI 事件. 2024 年 9 月 7 日. WD. URL: https://w3org.cn/TR/uievents/
    [WEBIDL]
    Edgar Chen; Timothy Gu. Web IDL 标准. Living Standard. URL: https://webidl.spec.whatwg.org/

    参考资料

    [CSS-UI-4]
    Florian Rivoal. CSS Basic User Interface Module Level 4. 2021年3月16日. WD. URL: https://w3org.cn/TR/css-ui-4/
    [CSS-WRITING-MODES-3]
    Elika Etemad; Koji Ishii. CSS Writing Modes Level 3. 2019年12月10日. REC. URL: https://w3org.cn/TR/css-writing-modes-3/

    IDL 索引

    enum ScrollBehavior { "auto", "instant", "smooth" };
    
    dictionary ScrollOptions {
        ScrollBehavior behavior = "auto";
    };
    dictionary ScrollToOptions : ScrollOptions {
        unrestricted double left;
        unrestricted double top;
    };
    
    partial interface Window {
        [NewObject] MediaQueryList matchMedia(CSSOMString query);
        [SameObject, Replaceable] readonly attribute Screen screen;
        [SameObject, Replaceable] readonly attribute VisualViewport? visualViewport;
    
        // browsing context
        undefined moveTo(long x, long y);
        undefined moveBy(long x, long y);
        undefined resizeTo(long width, long height);
        undefined resizeBy(long x, long y);
    
        // viewport
        [Replaceable] readonly attribute long innerWidth;
        [Replaceable] readonly attribute long innerHeight;
    
        // viewport scrolling
        [Replaceable] readonly attribute double scrollX;
        [Replaceable] readonly attribute double pageXOffset;
        [Replaceable] readonly attribute double scrollY;
        [Replaceable] readonly attribute double pageYOffset;
        undefined scroll(optional ScrollToOptions options = {});
        undefined scroll(unrestricted double x, unrestricted double y);
        undefined scrollTo(optional ScrollToOptions options = {});
        undefined scrollTo(unrestricted double x, unrestricted double y);
        undefined scrollBy(optional ScrollToOptions options = {});
        undefined scrollBy(unrestricted double x, unrestricted double y);
    
        // client
        [Replaceable] readonly attribute long screenX;
        [Replaceable] readonly attribute long screenLeft;
        [Replaceable] readonly attribute long screenY;
        [Replaceable] readonly attribute long screenTop;
        [Replaceable] readonly attribute long outerWidth;
        [Replaceable] readonly attribute long outerHeight;
        [Replaceable] readonly attribute double devicePixelRatio;
    };
    
    [Exposed=Window]
    interface MediaQueryList : EventTarget {
      readonly attribute CSSOMString media;
      readonly attribute boolean matches;
      undefined addListener(EventListener? callback);
      undefined removeListener(EventListener? callback);
               attribute EventHandler onchange;
    };
    
    [Exposed=Window]
    interface MediaQueryListEvent : Event {
      constructor(CSSOMString type, optional MediaQueryListEventInit eventInitDict = {});
      readonly attribute CSSOMString media;
      readonly attribute boolean matches;
    };
    
    dictionary MediaQueryListEventInit : EventInit {
      CSSOMString media = "";
      boolean matches = false;
    };
    
    [Exposed=Window]
    interface Screen {
      readonly attribute long availWidth;
      readonly attribute long availHeight;
      readonly attribute long width;
      readonly attribute long height;
      readonly attribute unsigned long colorDepth;
      readonly attribute unsigned long pixelDepth;
    };
    
    partial interface Document {
      Element? elementFromPoint(double x, double y);
      sequence<Element> elementsFromPoint(double x, double y);
      CaretPosition? caretPositionFromPoint(double x, double y, optional CaretPositionFromPointOptions options = {});
      readonly attribute Element? scrollingElement;
    };
    
    dictionary CaretPositionFromPointOptions {
      sequence<ShadowRoot> shadowRoots = [];
    };
    
    [Exposed=Window]
    interface CaretPosition {
      readonly attribute Node offsetNode;
      readonly attribute unsigned long offset;
      [NewObject] DOMRect? getClientRect();
    };
    
    enum ScrollLogicalPosition { "start", "center", "end", "nearest" };
    dictionary ScrollIntoViewOptions : ScrollOptions {
      ScrollLogicalPosition block = "start";
      ScrollLogicalPosition inline = "nearest";
      ScrollIntoViewContainer container = "all";
    };
    
    enum ScrollIntoViewContainer { "all", "nearest" };
    
    dictionary CheckVisibilityOptions {
        boolean checkOpacity = false;
        boolean checkVisibilityCSS = false;
        boolean contentVisibilityAuto = false;
        boolean opacityProperty = false;
        boolean visibilityProperty = false;
    };
    
    partial interface Element {
      DOMRectList getClientRects();
      [NewObject] DOMRect getBoundingClientRect();
    
      boolean checkVisibility(optional CheckVisibilityOptions options = {});
    
      undefined scrollIntoView(optional (boolean or ScrollIntoViewOptions) arg = {});
      undefined scroll(optional ScrollToOptions options = {});
      undefined scroll(unrestricted double x, unrestricted double y);
      undefined scrollTo(optional ScrollToOptions options = {});
      undefined scrollTo(unrestricted double x, unrestricted double y);
      undefined scrollBy(optional ScrollToOptions options = {});
      undefined scrollBy(unrestricted double x, unrestricted double y);
      attribute unrestricted double scrollTop;
      attribute unrestricted double scrollLeft;
      readonly attribute long scrollWidth;
      readonly attribute long scrollHeight;
      readonly attribute long clientTop;
      readonly attribute long clientLeft;
      readonly attribute long clientWidth;
      readonly attribute long clientHeight;
      readonly attribute double currentCSSZoom;
    };
    
    partial interface HTMLElement {
      readonly attribute Element? scrollParent;
      readonly attribute Element? offsetParent;
      readonly attribute long offsetTop;
      readonly attribute long offsetLeft;
      readonly attribute long offsetWidth;
      readonly attribute long offsetHeight;
    };
    
    partial interface HTMLImageElement {
      readonly attribute long x;
      readonly attribute long y;
    };
    
    partial interface Range {
      DOMRectList getClientRects();
      [NewObject] DOMRect getBoundingClientRect();
    };
    
    partial interface MouseEvent {
      readonly attribute double screenX;
      readonly attribute double screenY;
      readonly attribute double pageX;
      readonly attribute double pageY;
      readonly attribute double clientX;
      readonly attribute double clientY;
      readonly attribute double x;
      readonly attribute double y;
      readonly attribute double offsetX;
      readonly attribute double offsetY;
    };
    
    partial dictionary MouseEventInit {
      double screenX = 0.0;
      double screenY = 0.0;
      double clientX = 0.0;
      double clientY = 0.0;
    };
    
    enum CSSBoxType { "margin", "border", "padding", "content" };
    dictionary BoxQuadOptions {
      CSSBoxType box = "border";
      GeometryNode relativeTo; // XXX default document (i.e. viewport)
    };
    
    dictionary ConvertCoordinateOptions {
      CSSBoxType fromBox = "border";
      CSSBoxType toBox = "border";
    };
    
    interface mixin GeometryUtils {
      sequence<DOMQuad> getBoxQuads(optional BoxQuadOptions options = {});
      DOMQuad convertQuadFromNode(DOMQuadInit quad, GeometryNode from, optional ConvertCoordinateOptions options = {});
      DOMQuad convertRectFromNode(DOMRectReadOnly rect, GeometryNode from, optional ConvertCoordinateOptions options = {});
      DOMPoint convertPointFromNode(DOMPointInit point, GeometryNode from, optional ConvertCoordinateOptions options = {}); // XXX z,w turns into 0
    };
    
    Text includes GeometryUtils; // like Range
    Element includes GeometryUtils;
    CSSPseudoElement includes GeometryUtils;
    Document includes GeometryUtils;
    
    typedef (Text or Element or CSSPseudoElement or Document) GeometryNode;
    
    [Exposed=Window]
    interface VisualViewport : EventTarget {
      readonly attribute double offsetLeft;
      readonly attribute double offsetTop;
    
      readonly attribute double pageLeft;
      readonly attribute double pageTop;
    
      readonly attribute double width;
      readonly attribute double height;
    
      readonly attribute double scale;
    
      attribute EventHandler onresize;
      attribute EventHandler onscroll;
      attribute EventHandler onscrollend;
    };
    
    

    问题索引

    用户代理对于此操作是使用(协调后的)视口 执行滚动,还是在布局视口的滚动框上使用 滚动框 执行滚动 尚未达成一致。
    对象 IDL 片段重定义了一些成员。我们能以某种方式解决这个问题吗?
    DOM 顺序

    p1 = 左上角,即使在 RTL 中也是如此

    缩放为 0 表示除以零,返回 0x0

    不允许跨框架,抛出 WrongDocumentError?

    点被平坦化(3D 变换),z=0,类似于 getClientRect

    测试块级元素在行内元素中

    伪元素 before/after 是元素的子级

    视口盒子都是一样的

    ...
    ...
    ...
    scrollend 事件按照什么顺序分发?是基于滚动开始还是滚动完成排序?
    CanIUse

    支持情况:Android 浏览器3+百度浏览器13.52+Blackberry 浏览器10+Chrome9+Chrome for Android139+Edge12+Firefox6+Firefox for Android142+IE10+IE Mobile10+KaiOS 浏览器2.5+Opera12.1+Opera Mini全部Opera Mobile12.1+QQ 浏览器14.9+Safari5.1+iOS Safari5.0+Samsung Internet4+UC 浏览器 for Android15.5+

    来源: caniuse.com (截至 2025-09-11)

    CanIUse

    支持情况:Android 浏览器2.1+百度浏览器13.52+Blackberry 浏览器7+Chrome4+Chrome for Android139+Edge12+Firefox18+Firefox for Android142+IE11+IE Mobile11+KaiOS 浏览器2.5+Opera11.6+Opera Mini全部Opera Mobile12+QQ 浏览器14.9+Safari3.1+iOS Safari3.2+Samsung Internet4+UC 浏览器 for Android15.5+

    来源: caniuse.com (截至 2025-09-11)

    CanIUse

    支持情况:Android 浏览器2.3+百度浏览器13.52+Blackberry 浏览器7+Chrome15+Chrome for Android139+Edge12+Firefox3+Firefox for Android142+IE6+IE Mobile10+KaiOS 浏览器2.5+Opera11+Opera Mini全部Opera Mobile12+QQ 浏览器14.9+Safari5+iOS Safari4.0+Samsung Internet4+UC 浏览器 for Android15.5+

    来源: caniuse.com (截至 2025-09-11)

    CanIUse

    支持情况:Android 浏览器139+百度浏览器13.52+Blackberry 浏览器Chrome44+Chrome for Android139+Edge14+Firefox48+Firefox for Android142+IEIE MobileKaiOS 浏览器2.5+Opera31+Opera MiniOpera Mobile80+QQ 浏览器14.9+Safari9+iOS Safari9.0+Samsung Internet4+UC 浏览器 for Android15.5+

    来源: caniuse.com (截至 2025-09-11)

    CanIUse

    支持情况:Android 浏览器139+百度浏览器13.52+Blackberry 浏览器Chrome61+Chrome for Android139+Edge79+Firefox36+Firefox for Android142+IEIE MobileKaiOS 浏览器2.5+Opera48+Opera MiniOpera Mobile80+QQ 浏览器14.9+Safari14+iOS Safari14.5+Samsung Internet8.2+UC 浏览器 for Android15.5+

    来源: caniuse.com (截至 2025-09-11)

    CanIUse

    支持情况:Android 浏览器2.3+百度浏览器13.52+Blackberry 浏览器7+Chrome4+Chrome for Android139+Edge12+Firefox12+Firefox for Android142+IE9+IE Mobile10+KaiOS 浏览器2.5+Opera10.6+Opera Mini全部Opera Mobile11+QQ 浏览器14.9+Safari4+iOS Safari4.0+Samsung Internet4+UC 浏览器 for Android15.5+

    来源: caniuse.com (截至 2025-09-11)

    CanIUse

    支持情况:Android 浏览器139+百度浏览器13.52+Blackberry 浏览器 (有限支持)7+Chrome61+Chrome for Android139+Edge79+Firefox36+Firefox for Android142+IE (有限支持)8+IE Mobile (有限支持)10+KaiOS 浏览器2.5+Opera48+Opera MiniOpera Mobile80+QQ 浏览器14.9+Safari16.0+iOS Safari16.0+Samsung Internet8.2+UC 浏览器 for Android15.5+

    来源: caniuse.com (截至 2025-09-11)