[译] 解决 100vw 下滚动条引起的问题

原文连接:Scrollbars & CSS Custom Properties,by  Louis Hoebregtsjavascript

Photo by Maria Teneva on Unsplashcss

摘要

  • Widows 系统中的滚动条是会占据视口空间的。
  • vw 单位没有将滚动条计算在内。
  • fixed 弹出框里的 fixed 按钮是相对视口定位的而非弹出框。

正文

做为一个 Windows 系统用户,我有时会注意到有些网站没有在 Windows 上测试。致使的问题之一就是,可能在什么地方会看见一个滚动条没有理由的出现!在 MacOs 系统中,当你不滚动页面是,滚动条默认是隐藏的。它们也不占据任何的视口空间,这就表示 100% 的 body 宽度等于 100% 的屏幕宽度。可是在 Windows 系统中,滚动条的宽度会从窗口的宽度中减掉。不提供的浏览器的滚动条宽度有所差别,但一般是 17px 宽。java

这里列出了我最近遇到的两个状况:浏览器

1. 在使用 vm 单位时

规范 中对 vw 单位的定义以下:app

视口百分比长度(viewport-percentage lengths)是相对于初始包含块(viewport-percentage lengths)的尺寸计算的。[...] 可是,咱们假设滚动条是不存在的。ide

说的很清楚了,滚动条是不会影响 vw 单位计算的。函数

下面的截屏中,div 的宽度设置成了 100vw。能够看见,由于垂直滚动条的存在,有两个问题。工具

首先,由于 div 太宽了,把横向滚动条戳出来了;其次,由于有垂直滚动条出现,在没有滚动横向滚动条的默认状况下,段落文本被滚动条覆盖裁剪了。post

.container {
  width: 100vw;
}
复制代码

2. 在使用 fixed 弹出框时

我在实现弹出框的时候,一般会为弹出框指定一个宽度还有 overflow: auto; 样式。这样,若是弹出框里的内容不少,用户能够滚动内容。可是用户也可使用关闭按钮关闭弹框,但我但愿滚动的时候关闭按钮也是可见的。所以,在弹出框中我将关闭按钮 position: fixed; 了。学习

下面是我想实现的效果。在没有出现滚动条的时候,一切正常。

这是关闭按钮使用的样式:

.close {
  position: fixed;
  top: 40px;
  right: 40px;
}
复制代码

当弹框内容不少时。滚动条出现,此时关闭按钮的对齐就不是很完美了,由于按钮的左偏移值是相对视口的。这就显得左边比上边的偏移距离要小了。

解决方法

以后我学习了关于 CSS 自定义属性(也称为 CSS 变量)方面的知识,我想到能够声明一个变量用来存储滚动条宽度。这样一来,我就能够继续使用 vw 定位元素而无需担忧是在 Mac 仍是在 Windows 上。

首先须要计算出滚动条宽度。我建立了一个小工具函数,利用 JavaScript 建立的一个临时元素,获得滚动条宽度并返回。

const getScrollbarWidth = () => {
  // Create a temporary div container and append it into the body
  const container = document.createElement('div');
  // Append the container in the body
  document.body.appendChild(container);
  // Force scrollbar on the container
  container.style.overflow = 'scroll';

  // Add ad fake div inside the container
  const inner = document.createElement('div');
  container.appendChild(inner);

  // Calculate the width based on the container width minus its child width
  const width = container.offsetWidth - inner.offsetWidth;
  // Remove the container from the body
  document.body.removeChild(container);

  return width;
};

// Get the scrollbar dimension
const scrollbarWidth = getScrollbarWidth();
// Set a custom property with the value we calculated
document.documentElement.style.setProperty('--scrollbar', `${scrollbarWidth}px`);
复制代码

在 CSS 中,我建立一个默认变量,以防 Javascript 未启用或触发错误。

:root {
  --scrollbar: 0px;
}
复制代码

如今咱们有了一个包含浏览器滚动条宽度的变量,能够直接在 CSS 中使用它!

.container {
  width: 100vw; /* Fallback for old browsers */
  width: calc(100vw - var(--scrollbar));
}
复制代码

下面是关闭按钮的样式:

.close {
  position: fixed;
  top: 40px;
  right: 40px; /* Fallback for old browsers */
  right: calc(40px + var(--scrollbar));
}
复制代码

我但愿这篇文章能对你的项目有所帮助!别忘了在 Windows 电脑上测试你的网站哦🤭

(正文完)


广告时间(长期有效)

我有一位好朋友开了一间猫舍,在此帮她宣传一下。如今猫舍里养的都是布偶猫。若是你也是个爱猫人士而且有须要的话,不妨扫一扫她的【闲鱼】二维码。不买也没关系,看看也行。

(完)

相关文章
相关标签/搜索