让我们看一个基本的页面内链接
<a href="#section-two">Section Two</a>
点击后,浏览器将滚动到具有该 ID 的元素:<a href="#section-two">第二部分</a>
。这几乎和浏览器本身一样古老的浏览器功能。
但是,一旦使用 position: fixed;
,它就变成了一个问题。浏览器仍然会跳转以使新目标元素进入视野,但该元素可能会被固定位置元素遮挡,这对于 用户体验 来说非常糟糕。
近 10 年前,我称之为 “撞击浏览器窗口”,并介绍了一些可能的解决方案。Nicolas Gallager 记录了五种不同的技术。我什至在 CSS-Tricks 的 v17 版本中使用了固定位置的页眉,而且我不太喜欢其中任何一种技术。我有点放弃了,并在所有 <h3>
元素中添加了顶部填充,这足以容纳页眉。

但是有一种新方法!终于!
Šime Vidas 在 Web Platform News 中记录了这一点。作为 CSS 滚动捕捉 的一部分,有许多 CSS 属性可以一起使用,但事实证明 scroll-padding
和 scroll-margin
可以在滚动捕捉容器之外使用。
html {
scroll-padding-top: 70px; /* height of sticky header */
}
当这篇文章首次发表时,它只适用于 Chrome,但随着我在 2021 年 4 月更新这篇文章,它也适用于 Firefox 和 Safari!
Hiroyuki Ikezoe 写信告诉我,<body>
不是使用 scroll-padding
的正确位置,因为 document.scrollingElement
实际上是 <html>
。不幸的是,Chrome(v73)的实现方式是它目前只能在 <body>
上工作,但已经提交了一个错误报告,并且可能的结果是它将不再在 <body>
上工作,而只在 <html>
上工作。这与 原生规范的自定义滚动条 情况相同:它们只在 <html>
上工作。
不幸的是,如果你没有为你的粘性页眉设置静态/固定高度(应该不惜一切代价避免这种情况),它仍然不是很有用。无论如何都需要 JavaScript 来测量高度以调整样式。
为什么应该“不惜一切代价”避免使用固定高度的页眉?
回复 Todd,因为在 CSS 中设置固定高度通常是一个坏主意。网络的制作是为了适应它所呈现的任何形状和形式。用户设置了不同的字体大小,那么现在你的固定高度页眉就太短了。即使你使用
em
单位,你仍然需要跟踪所有高度(初始视图,滚动时高度可能会缩小,平板电脑上的变化,移动设备上的变化等等)。这会变成一个巨大的麻烦。一个月后,老板要求你在页眉导航菜单下方添加一个合作伙伴徽标,现在你必须再次调整所有这些高度,并再次调整你的页面内链接偏移量。这些只是固定高度/宽度给你带来的噩梦的几个例子。如果你没有固定的导航栏怎么办?我有一个视差效果背景,它的上半部分隐藏在我的导航栏下面,我无法让它滑下来。
我的天,我真的希望这能在所有浏览器中实现。为了用户体验,固定页眉现在越来越普遍。不用诉诸 js 来“劫持和重新实现”一个长期存在的通用功能,这很有帮助。
不知道为什么你需要所有这些变通方法……甚至是这个新的……如果你有一个固定的页眉,只需把它放在顶部,然后把其他所有东西都放在一个可滚动的
<
div> 中。
抱歉,我不明白你的最后一个演示,你已经使用
margin
向下推了内容,因此scroll-padding-top
没有做任何事情(删除它之后没有任何变化)。我是不是漏掉了什么?点击演示顶部的跳转链接。它的锚定位置以及它下面显示标题所允许的空间就是神奇之处。:)
太棒了!我一直被这个问题困扰了很久,以至于我大多试图忽略滚动链接。希望 webkit 和 firefox 尽快采用这个功能:)
谢谢 Chris,我还没见过这些属性!
这太棒了!不久前我不得不为一个客户做这件事,我用 JavaScript 修复了它,但这要好得多。
我实际上使用自定义属性来存储页眉的高度,然后你可以使用该变量计算值来偏移事物
你有没有考虑过给元素添加一个顶部边距?
这种技术效果很好,即使在旧的浏览器中也是如此,并且不需要任何 JavaScript。由于浏览器将目标元素与
<html>
元素的顶部对齐,因此你可以完全控制目标元素在页面上的跳转位置(因此不会再撞击浏览器窗口)。页眉和其他元素可以使用标准技术(必要时使用负边距)进行定位。
我认为这会添加边距/填充作为不可见部分,并且仅由快速链接使用。