防止窗口滚动条切换时的布局偏移

Macbook pro on brown wooden table
Published on
/5 mins read/---

滚动条什么时候会切换?例如:

  • 打开包含大量内容的模态框弹出层抽屉,并阻止用户滚动窗口
  • 切换手风琴标签页,它们展开后会增加文档高度,从而显示滚动条。
  • ...

Windows设备上,这些情况会导致布局偏移。这是因为滚动条被添加到窗口中,使窗口的宽度变小。 这种体验对用户来说并不好。

所以让我们用CSS来防止这种布局偏移。

经典修复方法

CSS3global.css
html {
  overflow-y: scroll;
}

经典的修复方法是给html元素添加overflow-y: scroll。这会始终在窗口上显示滚动条(即使内容高度小于视口高度)。

在这种情况下,滚动条始终可见。当窗口不可滚动时,其背景会变成灰色。

当然,我不推荐这个解决方案😅,因为我觉得它看起来和原问题一样糟糕。

使用视口宽度

更好的解决方案是给html元素添加一个不可见的margin-left,宽度与滚动条相同。 当滚动条被添加到窗口时,这个margin-left会变得可见;当滚动条从窗口移除时,它会变得不可见。

但是如何获取滚动条的宽度呢🤔?

答案是使用vw单位。

如果你还不知道,vw视口宽度是一个CSS单位,就像px%rem一样,但它相对于视口的宽度。 100vw等同于视口宽度的100%(包括滚动条),而100%宽度(对于html元素)等同于视口宽度的100%(不包括滚动条)🤯

所以,我们可以通过使用CSS的calc()函数从100vw宽度中减去100%宽度来计算滚动条的宽度,像这样:

CSS3global.css
html {
  margin-left: calc(100vw - 100%);
}

窗口不可滚动时,margin-left值等于0;当窗口可滚动时,等于滚动条的宽度。

NOTE

如果你使用这种方法防止布局偏移,并且你的应用程序有fixed定位的元素(如弹出层模态框),当它们打开时会用overflow-y: hidden样式阻止窗口滚动, 那么你也应该给fixed元素添加相同的margin-left

例如:

CSS3global.css
html,
.popup-overlay,
.modal-overlay {
  margin-left: calc(100vw - 100%);
}

另一个解决方案是将html元素的宽度设置为100vw并防止水平滚动:

CSS3global.css
html {
  width: 100vw;
  overflow-x: hidden;
}

这个解决方案只有在你的应用程序不需要水平滚动时才有意义(比如博客或文档网站)。 我在我的博客中使用了这种方法,你可以打开开发者工具检查html的样式来查看😊。

无代码方式⭐

有2种方法可以在不编写任何CSS代码的情况下防止布局偏移:

  • 第一种是告诉你的用户不要使用Windows设备,而是使用MacLinux设备😆

  • 第二种是就...保持原样,有时这不是什么大问题,你的用户实际上并不在乎这个🤷‍♂️

如果你有其他解决方案,请在下面的评论中告诉我。

愉快地编写样式🍻