我的个人博客

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

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;
}

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

无代码方式

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

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

  • 第二种是就...保持原样,有时这不是什么大问题,你的用户实际上并不关心这一点

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

愉快的样式设计