ScrollBar兼容问题

1,641 阅读3分钟

后台管理系统,使用antd的组件,当页面存在滚动条时,有两个操作在windows系统中会导致页面抖动。PS:body未进行特殊定位。

1. 问题场景

1. 在存在滚动条的情况下,如果header使用fixed布局,在弹窗打开关闭的情况下,Header的内容出现左右抖动。页面其他内容看起来正常。

2. 在页面内容过多出现滚动条的情况下,如果进行搜索进行查找,查找结果的内容不足以占一屏时。进行“查询”“重置”操作,页面整体出现抖动。

2. 分析原因

1.除fixed布局其他不抖动原因

antd的Modal组件处理了滚动条导致的页面抖动的问题。

windows中滚动条的宽度为17px(Chrome和FireFox)

当弹窗出现的时候,一般都在body上设置:

style="overflow: hidden"

此时滚动条消失。如果不进行任何处理,内容会随着滚动条消失而整体右移动。antd的组件通过设置body的宽度为:

style="width: calc(100% - 17px)"

来避免内容整体右移。

2. fixed布局抖动原因:

fixed布局的元素宽高不受body的影响。

当有滚动条时,其宽度为可视宽度 - 滚动条。当滚动条消失时,其宽度为可视宽度

当弹窗出现时,本质上是整体宽度增加,因为元素中的内容一般都是固定宽度居中显示。

随着弹窗出现和关闭,会出现“抖动”(打开内容向右移动,关闭又向左移动的现象)。

3. 查询内容变化抖动原因:

随着结果的变化,导致滚动条的变化,从而页面的内容宽度变化。原理同上。但是因为没有在内容变化时同Modal组件对滚动条进行处理,导致页面抖动。

3. 解决方案

综上原因,本质上是因为滚动条的出现和消失导致的内容移动。可以通过margin/padding来控制内容的布局。

例如:margin-right

当出现滚动条时,margin-right:-17px

当滚动条消失时,margin-right: 0

但是滚动条对于场景2的情形,不确定何时出现滚动条。就必须通过js监听滚动条是否出现,这很烦啊。

怎么才能直接通过css就搞定呢?

4. CSS计算宽度

说到css计算,最熟悉的就是css3新增的calc()方法。

calc()支持各种CSS单位计算。其中最常用的应该是width: calc(100%),其指的是有滚动条时为除滚动条之外的宽度, 否则则是整个屏幕的可视宽度。

而屏幕的可视宽度是包含滚动条在内的宽度,有另一个方便的属性:width: 100vm 。不随滚动条变化。

综上实时计算margin距离可以为:

margin-right: calc(100% - 100vm);

注意:如果使用padding, 则为padding-left, 但其不支持负数,需要注意运算顺序。