这是我从 Mac 上的开发者那里听到过很多次的建议,我也想再说一遍:进入 **系统偏好设置 > 常规 > 显示滚动条** 并将其设置为 **始终显示**。 这不是为了你,而是为了网页。 问题在于,如果没有此设置,你将永远不会遇到滚动条触发的布局偏移,但其他所有开启此设置的用户都会遇到。 因为你希望在设计时避免出现这种卡顿现象,所以你应该自己使用此设置。
以下是 Stefan Judis 演示视口单位的使用可能是原因之一
在那里,100vw
导致水平溢出,因为垂直滚动条已经出现,占据了部分空间。 在某种程度上,这感觉**非常错误**,但这就是现状。
Stefan 指向 Kilian Valkhof 的文章,介绍了如何处理这个问题。 经典的解决方案
简单的解决方法是使用
width: 100%
代替。 百分比不包含滚动条的宽度,因此会自动适应。如果无法这样做,或者你正在为其他元素设置宽度,请向周围的元素添加
Kilian Valkhof,“如何查找水平滚动条的原因”overflow-x: hidden
或overflow: hidden
以防止滚动条出现。
我认为这些都是解决方法,因为它们都不是你想要做的事情的精确匹配。
幸运的是,有一个即将推出的基于规范的解决方案。 Bramus 掌握了全部信息
在网页上显示滚动条时的副作用是,内容的布局可能会根据滚动条的类型而改变。
Bramus Van Damme,“使用scrollbar-gutter
CSS 属性 —很快就会随 Chromium 一起发布 — 旨在让我们开发者更好地控制这一点。scrollbar-gutter
CSS 属性防止滚动条引起的意外布局偏移”
听起来很有效,如果这成为 重置样式表 中非常常见的一行代码,我也不会感到惊讶
body {
scrollbar-gutter: stable both-edges;
}
不过,这让我好奇……在整个页面级别处理这个问题时,是使用 <body>
还是 <html>
? 在过去处理与滚动相关的事情时,这很奇怪。
我们真的能在所有浏览器中实现它吗? 谁知道呢。 看起来很有可能,但即使它接近实现,并且行为已规范化,我也会尝试使用它。 感觉对渐进增强友好。
最近遇到了一些滚动问题,并且很遗憾地发现 overscroll 属性的支持很差。 能够选择是否使用那种小巧的弹跳效果当然会很棒
我总是不得不使用自定义属性和 JavaScript 滚动条宽度检测来修复这个问题。 在 CSS 中拥有能够解决这个问题的东西会非常棒
这个领域发生了很多事情! 重要的交叉参考:https://www.w3.org/TR/css-values-4/#viewport-relative-lengths
虽然隐藏溢出显然是一种解决方法,但我认为 100% 不是。
在顶级元素上,100% 的行为类似于 100vw,除了它会执行你期望它执行的操作,即排除滚动条。 正如你所说,100vw 的行为“在某种程度上,这感觉非常错误,但这就是现状”。
这里的区别在于,根据规范,视口单位使用初始包含块(其大小包括滚动条),而百分比单位使用包含块,该包含块是动态的,并在滚动条出现时减去滚动条。
我不确定 scrollbar-gutter 是否是最佳解决方案,因为它具有(预期)副作用,即即使不需要也始终为滚动条预留视觉空间。 在这方面,它有点像 overflow: scroll。
关于哪个元素是 scrollingElement,你可以检查
document.scrollingElement
。 虽然它过去因浏览器而异,但它们已确定使用html
元素作为默认滚动容器。最后,只想在这里抛砖引玉,但下一个主要版本的 Polypane 将检测 100vw 问题并为开发人员发出警告/通知
1000% 同意! 从 10 年前我开始使用 Mac(10 年前)以来,我一直使用“始终显示滚动条”。 我从来不喜欢在内容可滚动时没有视觉指示。 始终显示滚动条的有趣之处在于,你可以看到有多少开发人员从未了解过
overflow:auto
和overflow:scroll
之间的区别。我完全同意网页开发者应该使用默认设置测试他们的网站,因为这正是他们的用户将体验到的。
我认为值得一提的是,默认隐藏滚动条不利于可用性。 它消除了提示功能, 除了本文中提到的布局偏移之外。 需要记住的是,仅仅因为 macOS 自动隐藏滚动条,并不意味着我们应该在我们的设计工作中复制这种设计。
啊,水平溢出的恐怖……
此错误的根源可以追溯到 IE6 中的 position:absolute 与 position:fixed 困境^^
偶尔需要思考一下这个问题,但这也会让我保持专注。
我做了一些实验(在 Chrome 中,在 Mac 上),发现混淆源于我们对包含滚动条的内容的预期。
在
div
元素上设置固定宽度(例如100px
)并为其分配overflow: auto
,会导致滚动条出现在div
的边界框内,正如我们所期望的那样。div
内容的可用水平空间会减少滚动条的宽度(暂时忽略box-sizing
和填充)。但是,将元素(例如
body
)的宽度设置为100vw
会导致类似于将上述div
的包含元素之一的宽度设置为100px
的情况,在这种情况下会出现水平滚动条。 显然,当我们让body
的内容正常流动时看到的滚动条实际上并不包含在body
元素本身(也不包含在html
元素中)。通过稍微调整一下,我发现可以通过在
html
和body
元素上设置height: 100%; overflow: auto;
来获取body
包含框内的视觉上最外层的滚动条。 但是,这并没有“修复”任何问题; 包含在body
中并分配width: 100vw
的元素仍然会导致水平滚动条出现(如果它具有position: absolute
,则可能不会出现)。