后台管理系统,使用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, 但其不支持负数,需要注意运算顺序。