是否可以在没有滚动条的情况下计算视口宽度(vw)?

Mar*_*der 56 css viewport-units

如标题中所述,是否可以vw仅在css中计算没有滚动条的情况?

例如,我的屏幕宽度为1920px.vw回来1920px,太好了.但我的实际身体宽度只是像1903px.

有没有办法让我1903px只用css 检索值(不仅是直接的孩子body),还是我绝对需要JavaScript呢?

小智 77

一种方法是使用calc.据我所知,100%是包括滚动条的宽度.所以,如果你这样做:

body {
  width: calc(100vw - (100vw - 100%));
}
Run Code Online (Sandbox Code Playgroud)

你得到100vw减去滚动条的宽度.

如果你想要一个占视口50%的正方形(减去scollbar宽度的50%),你也可以用高度来做这个.

.box {
  width: calc(50vw - ((100vw - 100%)/2))
  height: 0
  padding-bottom: calc(50vw - ((100vw - 100%)/2))
}  
Run Code Online (Sandbox Code Playgroud)

  • 这是惊人的,但遗憾的是,只有当您调整大小的元素是`body`的直接子元素或者与`body`具有相同宽度的元素时才有效(否则`100%`将引用错误元素的宽度).在这种情况下,您可以简单地使用百分比.除非我错过了什么? (29认同)
  • 数学:'100vw - (100vw - 100%)= 100vw - 100vw + 100%= 100%`我错过了什么吗? (29认同)
  • 对于100vw会计滚动条实际上​​是一个问题的情况是不行的 - 也就是说,当你需要将100vw块放入具有固定宽度的容器时. (7认同)
  • @TKoL 在他的解决方案实际解决问题的每种情况下, width:50% 也能正常工作。Kamil Kiełczewski 是对的,这个解决方案没用。 (5认同)
  • @KamilKiełczewski,当你想要一个全宽的东西时有效,但他在下面展示了一个有意义的例子,`calc(50vw - ((100vw - 100%)/ 2)) (2认同)
  • 不幸的是,这对于绝对定位的元素不起作用,因为那里100%不可用:( (2认同)
  • 同意@KamilKiełczewski 我不明白为什么这个答案有这么多声音。50vw - ((100vw - 100%)/2) = 50vw - (100vw/2 - 100%/2) = 50vw - (50vh - 50%) = 50% (2认同)
  • @KamilKiełczewski `100vw - (100vw - 100%)` 在 CSS 中减少为 `100vw - 15px`,这不等于 `100vw`。根据运算符优先级和单位转换的工作方式,同时减少 CSS 中的计算,数学是正确的。 (2认同)
  • @trusktr你是对的 - 在你的例子中“100vw - 15px”不等于“100vw”,但问题是这相当于“100%”。例如,假设 100vw=1015px 和 100%=1000px 那么你有: `100vw - (100vw - 100%) = 1015 - (1015-1000) = 1015-15 = 1000 = 100%` (2认同)
  • @KamilKiełczewski 哦,是的,这是有道理的。:) (2认同)

小智 25

我通过在文档加载后添加一行 javascript 来定义 CSS 变量来做到这一点:

document.documentElement.style.setProperty('--scrollbar-width', (window.innerWidth - document.documentElement.clientWidth) + "px");
Run Code Online (Sandbox Code Playgroud)

然后在 CSS 中,您可以使用var(--scrollbar-width)/不使用不同宽度的滚动条对不同的浏览器进行所需的任何调整。如果需要,您可以对水平滚动条执行类似的操作,将innerWidthwithinnerHeightclientWidthwith替换clientHeight

  • 这是一个非常好的解决方案,但如果我没看错的话,只有当文档加载的第一页已经有滚动条时,这才有效。如果它加载一个短页面 --scrollbar-width 将为 0,即使文档变大, (4认同)

Lar*_*zan 21

复制和粘贴解决方案

这是一个简单的嵌入式解决方案,基于 user11990065 的答案,用于设置 css 变量--scrollbar-width并在调整大小时保持更新。它还根据 DOMContentLoaded 和加载事件进行计算,这样您就不必担心初始渲染阶段的大小变化。

您只需将其复制并粘贴到您的代码中,因为它是普通 JS(或者将其包装在“脚本”标记中,然后将其直接粘贴到您的 HTML 代码中:

function _calculateScrollbarWidth() {
  document.documentElement.style.setProperty('--scrollbar-width', (window.innerWidth - document.documentElement.clientWidth) + "px");
}
// recalculate on resize
window.addEventListener('resize', _calculateScrollbarWidth, false);
// recalculate on dom load
document.addEventListener('DOMContentLoaded', _calculateScrollbarWidth, false); 
// recalculate on load (assets loaded as well)
window.addEventListener('load', _calculateScrollbarWidth);
Run Code Online (Sandbox Code Playgroud)

如果页面中存在可能显示/隐藏滚动条的动态高度变化,您可能需要查看“检测文档高度变化”,您可以使用它来触发高度变化的重新计算。

由于该值是使用 JS 计算并设置为固定值,因此您可以在 CSS 的计算操作中使用它,如下所示:

.full-width {
  width: calc(100vw - var(--scrollbar-width));
}
Run Code Online (Sandbox Code Playgroud)

这将为.full-width提供准确的可用宽度。


jna*_*aas 7

body { overflow: overlay; }
Run Code Online (Sandbox Code Playgroud)

如果您不想让事情变得过于复杂,那么在某些情况下这可能就足够了。至少它很好地解决了我的问题,因为内容和视口边缘之间有足够的空白(Windows 滚动条会重叠最右边 20 左右的像素)。

  • 仅供未来用户参考,“overlay”值已被列为已弃用且不适用于新网站 (4认同)

Mad*_*iha 5

根据规范,视口相对长度单位不考虑滚动条(实际上,假定它们不存在)。

因此,无论您的预期行为是什么,使用这些单元时都无法考虑滚动条。

  • 根据规范,vw 确实会带走滚动条宽度,除非溢出处于自动状态,否则它的工作方式就像 vw 值的“隐藏”一样。因此,如果页面必须溢出,请将其设置为“滚动”。使用overflow-x 和overflow-y 您可以选择要显示的滚动条。 (6认同)