小小小tip:避免滚动条显隐对页面其他元素的影响

Posted 恪愚

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小小小tip:避免滚动条显隐对页面其他元素的影响相关的知识,希望对你有一定的参考价值。

点这里直接到下面看解决方案

自古以来,滚动条都是用户体验大难关,也在不断进化。一者滚动条样式在浏览器间表现不一致,从而有人提出“顶部阅读进度”方案;二者在window下,滚动条本身是占位的!这就导致了天生考虑响应式的现代页面中元素会受到影响从而“跳动”。
经常有下面的场景的发生:

  • “加载更多”
  • 页面懒加载
  • 模板页面跳转/路由跳转

共同点都是:从不足一屏到超出一屏。

淘宝网首页使用CSS把页面尺寸布局骨架搭好,再在里面吐数据。
但即使是这样,他们还是做了overflow-x:hidden;。一方面是为了遮住横向的“白边”。另一方面也是因为:overflow一个方向设置了hidden,另一个方向会默认变为scroll!

新浪微博也是这样做的。甚至在某个页面直接对html标签设置了overflow-y: scroll;

但一直如此的话,势必会提到开头的问题:丑陋的滚动条一直存在。

回到文章开头那段话:“滚动条本身是占位的”。进而我们首先要知道一个区别 ——

  • 整体滚动(整个页面的滚动,body是不是呢?)
  • 局部滚动(某个块内的滚动)

可能这并没有什么值得注意的,因为这是笔者自己做的一个区分。毕竟对一个div设置 overflow 为 hidden 以外的值都可以说是「局部滚动」。但是你有没有想过,body也只是一个(特殊的)div…唔,或许也并不那么特殊。

笔者拿张鑫旭大神的一篇文章中的一个例子作为说明(想要详细探究的请移步原文:对html与body的一些研究与理解

我们对body设置:

body  background-color: aqua; 

就能看到:

然后再设置:

html  background-color: bisque; 

咦?
接下来再对body元素进行操作:

body 
   background-color: aqua;
   margin:100px; 
   border:30px solid #093;

嗯。nice。笔者这里并没有其他意思,只是想说明:body并不等于html —— 而在大多数开发时间里,很多人确实会将他们混为一谈。

接下来的两步是“承上启下”的存在 ——
首先,我们对body设置一个巨大的height值。并对 body 设置overflow-y: auto;
和 我们对body设置一个巨大的height值。并对 html 设置overflow-y: auto;

看,他们对滚动的掌控是一样的。但是我将对html的设置称为“整体滚动”,因为在我看来,这时候是整个body的位移;而对body的设置仅仅是对内容的完全展示 —— 这说法也许不对,但确实是直观的。

如何做

知道了这一点。我们就有了一个大体的解决思路:考虑到重绘对渲染性能的影响,让滚动条影响到body的偏移比影响到具体某个子元素的排列要好得多。所以,我们的解决方案中必须要着眼于两个点:body和滚动条的Layer!

让需要处理的元素有一个单独的层级是公认的性能缓解方案。我们可以对body这么做:

html 
  overflow-y: scroll;


:root 
  overflow-y: auto;
  overflow-x: hidden;


:root body 
  position: absolute;


body 
  width: 100vw;
  overflow: hidden;

一方面,在html层面提前为滚动条预留位置(这样,滚动条的有无也就仅仅是展示与否了,这也是Firefox的处理策略);
另一方面,禁止body内部滚动特性,并且将body整体脱离文档流拿到一个单独的渲染层。

:root是什么?
:root这个 CSS 伪类文档树的根元素。对于 HTML 来说,:root表示<html>元素,除了更高级别之外,与 html 选择器相同。
它也常被用在css自定义变量的定义上。

分析

目前来说,关于滚动条的解决方案都是要求「提前为滚动条部分预留位置」的。要么就要把滚动条从浏览器层面上脱离文档流。
之前看的张大书中的一种方法:

padding-left: calc(100vw - 100%);

也是如此。而且,考虑到响应式,这行代码需要配合@media在宽屏下作用。

所以,现在大多数网站,尤其是内容类网站,实际展示的区域都不是“贴边”的。或者干脆直接居中划出一个div —— 比如微信文章在浏览器的展示页。要么,就干脆花里胡哨的把右&下给遮过去。啧啧,也是难为了。

新方案

浏览器支持了一个新属性:scrollbar-gutter,用来让出现滚动条时内容不跳动。但,,,支持程度很低很低。不过也算是浏览器厂商为用户体验做的又一次贡献了。感兴趣可以移步MDN看下


技术圈并不新鲜事

  • 2021年,前端技术逐步稳定。拿css来看,新属性频率越来越低、突破性属性占比很高。其中越来越偏向用户体验靠拢。Chrome仍会是响应最及时的浏览器(毕竟“用户体验”、“用户安全”这两件事在Chrome身上的变化相信很多关注的人都有感受的)

以上是关于小小小tip:避免滚动条显隐对页面其他元素的影响的主要内容,如果未能解决你的问题,请参考以下文章

小tips:页面滚动到关闭时的位置与不滚动

小tips:页面滚动到关闭时的位置与不滚动

小tips:页面滚动到关闭时的位置与不滚动

element 一个页面两个table显隐相互影响

盒子的显隐

滚动条挤占内容宽度,影响布局