Firefox 66 中的滚动锚定

Firefox 66 于 3 月 19 日发布,包含一项名为滚动锚定的功能。

它基于 新的 CSS 规范,该规范最初由 Chrome 实现,现在可以在 Firefox 中使用。

您是否以前遇到过这种情况?

正在阅读标题,但随后加载了一个广告,将您正在阅读的内容移出了屏幕。

或者怎么样?

您旋转手机,但现在您找不到您刚刚阅读的段落。

这两个问题都有一个共同的原因。

浏览器通过跟踪您离页面顶部的距离来滚动。当您四处滚动时,浏览器会增加或减少您离顶部的距离。

但是,如果在您阅读的地方上方加载了一个广告,会发生什么?

浏览器使您保持与页面顶部相同的距离,但现在您正在阅读的内容和顶部之间有更多内容。实际上,这会将页面的可见部分向上移开您正在阅读的内容(并且通常移入刚刚加载的广告)。

或者,如果您将手机旋转到纵向模式?

现在屏幕上的水平空间要少得多,高度为100px的段落现在可能高度为200px。如果您正在阅读的段落旋转前离页面顶部1000px,它现在旋转后可能离页面顶部2000px。如果浏览器仍然滚动到1000px,您将看到您之前远在上面的内容。

解决这些问题的关键在于,用户并不关心他们离页面顶部的距离。他们关心的是他们相对于他们正在查看的内容的位置!

滚动锚定 致力于锚定用户到他们正在查看的内容。当此内容因广告、屏幕旋转、屏幕调整大小或其他原因而移动时,页面现在滚动以使您保持与它的相对位置。

演示

让我们看一些滚动锚定的实际示例。

这是一个 页面,其中有一个滑块,它会更改页面顶部元素的高度。滚动锚定可以防止视窗上方的元素更改您正在查看的内容。

这是一个 页面,它使用 CSS 动画和转换来更改页面上元素的高度。即使段落因动画而移动,滚动锚定也能让您一直看到同一个段落。

最后,这里有原始的屏幕旋转视频,滚动锚定处于禁用状态,与滚动锚定处于启用状态的视图形成对比。

注意到当滚动锚定处于禁用状态时,我们会跳转到一个无关的区域?

工作原理

滚动锚定首先选择 DOM 中的一个元素作为 锚点节点,然后尝试将该节点保持在屏幕上的相同相对位置。

为了选择一个锚点节点,滚动锚定使用 锚点选择算法。该算法试图选择靠近页面顶部的小内容。确切的步骤稍微复杂,但大致上它是通过遍历 DOM 中的元素,并选择第一个在屏幕上可见的元素来实现的。

当一个新元素添加到页面中,或屏幕旋转/调整大小时,需要重新计算页面的布局。在此过程中,我们检查锚点节点是否已移动到新位置。如果是,我们会滚动以使页面保持与锚点节点的相同相对位置。

最终结果是,锚点节点上方的页面布局更改无法更改锚点节点在屏幕上的相对位置。

Web 兼容性

新功能很棒,但它们会破坏用户的网站吗?

此功能是一个 干预。它打破了 Web 的既定行为,以解决用户的烦恼。

这类似于浏览器过去如何阻止弹出式广告,以及目前阻止自动播放音频和视频的工作。

这种类型的解决方法存在一定风险,因为现有网站对滚动工作原理抱有期望。

滚动锚定通过几个 启发式 来缓解风险,这些启发式会在导致现有网站出现问题的场景中禁用该功能。

此外,还引入了一个新的 CSS 属性,overflow-anchor,允许网站选择退出滚动锚定。

要使用它,只需在您不想使用滚动锚定的任何滚动元素上添加overflow-anchor: none。此外,您可以将overflow-anchor: none 添加到要从被选为锚点节点中排除的特定元素上。

当然,与现有网站仍然可能存在兼容性问题。如果您发现由滚动锚定引起的新问题,请 提交错误报告

未来的工作

现在在 Firefox 66 中发布的滚动锚定版本是我们的初始实现。在接下来的几个月中,我们将继续改进它。

最重要的工作将涉及改进用于选择锚点的算法。

当滚动锚定选择一个靠近屏幕顶部的小锚点时,它最有效。

  1. 如果锚点太大,它内部的内容可能会以我们无法调整的方式扩展或缩小。
  2. 如果锚点离屏幕顶部太远,您正在查看的内容下方的内容可能会扩展,并导致不需要的滚动调整。

我们发现,我们在规范中的实现可能会在具有表格布局或overflow: hidden 中有大量内容的页面上选择不合适的锚点。

这是由于规范中的一个模糊区域,我们选择了一种与 Chrome 实现不同的方法。这是多个浏览器实现的价值之一:我们积累了丰富的滚动锚定经验,并希望将其应用到规范中,以确保它不受仅一个浏览器的实现细节的定义。

Firefox 中的滚动锚定功能由许多人开发。感谢 Daniel Holbert、David Baron、Emilio Cobos Álvarez 和 Hiroyuki Ikezoe 的指导和多次审查。

关于 Ryan Hunt

Ryan Hunt 的更多文章……


5 条评论

  1. 史蒂夫

    我可以预见到网站会将“overflow-anchor: none”添加到他们页面上的所有内容,以确保他们的广告仍然显示在页面顶部。是否会提供一个选项,允许用户告诉浏览忽略“overflow-anchor: none”?

    2019 年 3 月 28 日 下午 3:51

  2. mrv

    曾经有一段时间,我有一个通过 Web 应用程序控制的火箭发射系统。顶部有一个横幅。我想关闭火箭发射器,但不幸的是,当我点击时,横幅出现了,实际上我点击了“发射”按钮。从那以后,我附近的那个小镇就不复存在了。由于这次事故,我认为这是一个非常重要的功能。

    2019 年 3 月 29 日 上午 8:39

  3. Łukasz

    它工作不正常
    https://bugzilla.mozilla.org/show_bug.cgi?id=1540203&fbclid=IwAR1ozKGyyPdxkfw1oFYg1UiO7COMdqoeos6GlROxLAdYZaPrt9DBoLaKPus

    2019 年 3 月 29 日 下午 12:45

  4. Eric

    从用户的角度来看,这非常有用,谢谢!

    下一个:请移除所有现在到处使用的烦人模态窗口,这些窗口用于注册新闻通讯或类似的垃圾请求。拜托了。

    2019 年 3 月 29 日 下午 13:09

  5. Solomon Ucko

    关于屏幕旋转,一个更简单的解决方案是保持滚动位置相对于页面高度保持不变。

    2019 年 4 月 4 日 下午 16:27

本文的评论已关闭。