是否可以不使用滚动条计算视口宽度(vw) ?

正如标题中提到的,是否有可能只计算 CSS 中没有滚动条的 vw

例如,我的屏幕宽度为 1920pxvw返回 1920px,很好。但是我的实际身体宽度只有 1903px那么大。

有没有一种方法可以让我只使用 css 来检索 1903px值(不仅仅是针对 body的直接子代) ,或者我真的需要用到 JavaScript?

90716 次浏览

根据 < a href = “ https://drafts.csswg.org/css-values-3/# viewport-relent- 长度”rel = “ noReferrer”> the specs ,viewport 相对长度单元不考虑滚动条(事实上,假设它们不存在)。

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

Webkit 浏览器排除滚动条,其他浏览器将滚动条包含在返回的宽度中。 这当然可能会导致问题: 例如,如果您使用 ajax 动态生成内容,动态增加高度,Safari 可能会在页面可视化过程中从一个布局切换到另一个布局..。 好吧,这种情况不常发生,但是有些事情是需要注意的。 在移动端,问题较少,导致滚动条一般不显示。

也就是说,如果你的问题是精确地计算所有浏览器中没有滚动条的视窗宽度,据我所知,一个好的方法是这样的:

width = $('body').innerWidth();

先前规定的:

body {
margin:0;
}

一种方法是使用微积分。据我所知,100% 的宽度包括滚动条。因此,如果你这样做:

body {
width: calc(100vw - (100vw - 100%));
}

得到的是100vw 减去滚动条的宽度。

例如,如果您想要的正方形是视口的50% (减去 scolbar 宽度的50%) ,那么也可以对高度执行此操作

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

overflow-y设置为 auto时,vw单元不考虑 overflow-y滚动条。

将其更改为 overflow-y: scroll;vw单元将成为带滚动条的视口。然后可以使用 calc ()从 vw 值中减去滚动条大小。您还可以定义滚动条宽度,这样它将与浏览器无关。

这是唯一需要考虑的缺点。如果内容适合屏幕,滚动条还是会显示出来。可能的解决方案是在 javascript 中从 auto改为 scroll

只有这样我才能找到它,而不会把你的代码和“ Calc”搞混 将容器元素的大小设置为100vw; 为 overflow-x 添加容器周围的包装器; 这将使容器变为全宽,就像滚动条覆盖内容一样。

<!DOCTYPE html>
<html>
<head>
<style type="text/css">
html{ overflow-y: scroll; }
html, body{ padding:0; margin: 0;}
#wrapper{ overflow-x: hidden; }
.row{ width: 100vw; }
.row:after{ clear: both; content: ''; display: block; overflow: hidden; }
.row-left{ background: blue; float: left; height: 40vh; width: 50vw; }
.row-right{ background: red; float: right; height: 40vh; width: 50vw; }
</style>
</head>
<body>


<div id="wrapper">
<div class="row">
<div class="row-left"></div>
<div class="row-right"></div>
</div>
</div>




</body>
</html>

这不是我的解决方案,但有助于我创建下拉式全宽菜单与绝对在相对元素不完全与跨度。

我们应该使用 css var in: root 中的滚动条,然后使用它。

:root{
--scrollbar-width: calc(100vw - 100%);
}




div { margin-right: var(--scrollbar-width); }

Https://codepen.io/superkoders/pen/nwwyee

最简单的方法是将 html 和 body 设置为100vw:

html, body{ width:100vw; overflow-x: hidden; overflow-y: auto; margin: 0; }

唯一的问题是右边-如果显示滚动条,大部分将被剪切一点。

我通过添加一行 javascript 来定义一个 CSS 变量,一旦文档加载完成:

document.documentElement.style.setProperty('--scrollbar-width', (window.innerWidth - document.documentElement.clientWidth) + "px");

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

如果情况类似于滑块: 正如许多回答中提到的,宽度100% 不考虑滚动条,而100vw 考虑了。如果有许多元素需要获取窗口的宽度,并且它们已经嵌套在一个窗口宽度为100% 的容器中(或者其自然块宽度为100%) ,那么您可以使用:

  • 显示集装箱的弯曲度
  • Flex: 00100% 用于子元素

100vw = 带滚动条的屏幕宽度 100% = 没有滚动条的屏幕宽度

在测量屏幕宽度时,最好使用 calc (100%-50px)。即使在可以直接看到滚动条的 Windows 浏览器上,与 macOS 浏览器相比,返回的屏幕宽度也有所不同。

不行,没有 CSS 中的滚动条就无法计算 vw

但是,有一种方法可以解决 100vw ruined by the scrollbar on Windows问题。您必须创建一个全宽元素(在本例中为 row--full-width) ,该元素由 Flex 容器构成。这个解决方案同时适用于 Mac 和 Windows:

HTML:

<section>
<div class="container">
<div class="row--full-width"></div>
<div class="row">
<div class="card">
</div>
<div class="card">
</div>
</div>
</div>
</section>

正如您在上面的示例中看到的,row--full-width元素从容器中流出,即使有滚动条,它也与头部对齐。

在 Edge 18(Win)、 Edge 88(Win/Mac)和 Chrome88(Win/Mac)上进行了测试。

复制粘贴解决方案

这里是一个简单的 放入式溶液,放入式溶液的基础上用户11990065的 回答设置一个 css 变量 ——滚动条宽度,并保持它更新的大小。 它也是在 DOMContentLoadedandload 事件上计算的,这样您就不必担心在初始呈现阶段的大小变化。

你可以把它复制粘贴到你的代码中,就像普通的 JS 一样(或者把它包装在‘ script’标签中,然后直接粘贴到你的 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);

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

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

.full-width {
width: calc(100vw - var(--scrollbar-width));
}

这将给 。全宽确切的可用宽度。

body { overflow: overlay; }

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

可能只是长得很“丑”。

首先,您需要运行这个脚本,以便将滚动条宽度转换为 css 变量:

document.documentElement.style.setProperty('--scrollbar-width', (window.innerWidth - document.documentElement.clientWidth) + "px");

现在举个例子,如果你想要“真正的”80vw 这样做:

calc(0.8 * (100vw - var(--scrollbar-width)));

“真正的”40vw

calc(0.4 * (100vw - var(--scrollbar-width)));

只要你不期待任何实际的水平滚动,你可以使用这个:

body {
overflow-x: hidden;
}

这样就会隐藏由于 auto滚动 Y 而产生的微小的水平滚动。

我是在为自己的案子寻找答案时偶然发现这个问题的。

我想使用 WordPress 的解决方案在视口中心设置一个 div,视口的宽度就像通常的 .alignfull一样。

情况:

<html>
<body>
<div class="main">
<div class="continer">
<div class="row">
<div class="col-12">
<article>
<div class="content">
<div class="alignfull-or-alignwide">
<p>The content.</p>
</div>
</div>
</article>
</div>
</div>
</div>
</div>
</body>
</html>

我的解决办法是:

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


.alignfull-or-wide {
margin-right: calc(50% - 50vw);
margin-left: calc(50% - 50vw);
width: 100vw;
max-width: 100vw; // change this for wide or w/e.
}

这解决了我的问题,使文档的根像 viewport 一样宽。使用这种方法,您实际上忽略了任何滚动条的宽度。

通过设置为 100vw,我们消除了任何平台上滚动条的宽度。 通过设置溢出参数,我们可以防止 任何内容在 viewport 之外呈现。 通过设置边距,我们将 div 的左侧居中到它的相对位置父节点。这通常也是视窗的中心。 然后,负边距将它拉到视窗的左侧。 通过在右边做同样的操作,我们创建了 div 以页面为中心的错觉。

同样需要注意的是: 在 csswg 上的 滚动条宽度