防止100vw 创建水平滚动条

如果一个元素被设置为 width: 100vw;,并且有一个垂直滚动条,那么该元素的宽度将等于视窗加上滚动条的宽度。

有可能阻止这一切吗?

有没有可能在不禁用整个页面的水平滚动的情况下防止这种情况发生?除了修改 css/markup 使元素的宽度为正文的100% 之外,我想不出任何东西。

在 Chrome Version 43.0.2357.81 m & FF 36.0.1和 Opera 20.0.1387.91中在 Windows 8.1上进行测试

下面是所要求的代码:

例子

Html

<div class="parent">
<div class="box"></div>
</div>
<div class="tall"></div>

CSS

body { margin: 0; }
html { box-sizing: border-box; }
*, *::before, *::after {
box-sizing: inherit;
position: relative;
}
.parent {
background: rgba(0, 0, 0, .4);
height: 100px;
width: 5rem;
margin-bottom: 25px;
}


.box {
position: absolute;
top: 0;
left: 0;
background: rgba(0, 0, 0, .4);
height: 50px;
width: 100vw;
}


.tall {
height: 100rem;
}
54841 次浏览

填充和边界可能会干扰。保证金也可以。使用 盒子大小计算包含这些属性的宽度。并且可以从宽度中移除边距(如果有的话)。

* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
body {
margin: 0; /* interferes with 100vw */
}
.parent {
width: 100vw;
max-width: 100%; /* see below */
}
.box {
width: 100%; /* For those good old-fashioned browsers with no vw or calc() support */
width: -webkit-calc(100vw - [your horizontal margin, if any]);
width: -moz-calc(100vw - [your horizontal margin, if any]);
width: calc(100vw - [your horizontal margin, if any]);
max-width: 100%
}

似乎你必须添加 max-width: 100%;,如果有一个回流,导致滚动条出现 之后的初始视口宽度计算。这似乎不会发生在没有干扰滚动条(iOS,OS X,IE11 Metro)的浏览器中,但可以影响所有其他浏览器。

具有 width: 100vw的元素只有在其父元素之一具有水平填充时才会产生水平滚动条。否则它应该很适合。

检查这个小提琴: http://jsfiddle.net/1jh1cybc/ .parent2有一个填充,这导致内部的 .box打破了它的父宽度。

编辑:

在你的情况下,我想你的 body有一个保证金。检查您的代码并尝试删除主体 css 规则: http://jsfiddle.net/1jh1cybc/1/

基本上答案是否定的,如果你有一个垂直滚动条,就没有办法使100vw 等于可见视图的宽度。以下是我为这个问题找到的解决办法。

警告: < em > 我还没有测试这些解决方案是否支持浏览器


博士

如果您需要一个元素是100% 宽度的可见视区(视区减去滚动条) ,您将需要设置为100% 的主体。如果有一个垂直滚动条,就不能使用 vw 单元。


1. 设置所有祖先元素的静态位置

如果你确保所有的 .box的祖先都被设置为 position: static;,然后将 .box设置为 width: 100%;,这样它将是身体宽度的100% 。但这并不总是可能的。有时你需要一个祖先是 position: absolute;position: relative;

例子

将元素移到非静态祖先元素之外

如果不能将祖先元素设置为 position: static;,则需要将 .box移到祖先元素之外。这将允许您将元素设置为正文宽度的100% 。

例子

3. 删除垂直滚动条

如果不需要垂直滚动,可以通过将 <html>元素设置为 overflow-y: hidden;来删除垂直滚动条。

例子

4. 删除水平滚动条 这并不能解决问题,但可能适用于某些情况。

<html>元素设置为 overflow-y: scroll; overflow-x: hidden;将防止出现水平滚动条,但是100vw 元素仍然会溢出。

例子

视口-百分比长度规范

视窗百分比长度相对于 初始包含块。当初始块的高度或宽度 包含的块被改变,它们被相应地缩放。但是, 当根元素上的溢出值为 auto 时,任何滚动 条假定不存在。请注意,初始包含 控件上存在滚动条会影响块的大小 视窗。

似乎存在一个 bug,因为当溢出设置为在根元素上自动时,vw 单元应该只包含滚动条宽度。但是我已经尝试将根元素设置为 overflow: scroll;,它没有改变。

例子

我是这么做的:

div.screenwidth{
width:100%;  /* fallback for browsers that don't understand vw or calc */
width: calc(100vw - 17px); /* -17 because vw is calculated without the scrollbar being considered & 17px is width of scrollbars */
position:relative;  /* use this if the parent div isn't flush left */
right: calc((100vw - 17px - 100% )/2);

}

我在我的网站上通过添加 body { overflow-x: hide }来修复这个问题。

对你的榜样也有帮助。

这是一种更加成熟的解决 bug 的方法,因为它仍然存在于现代浏览器中。在许多情况下,设置 overflow-x: hidden可能会导致问题或不受欢迎。

这里有一个完整的例子: http://codepen.io/bassplayer7/pen/egZKpm

我的方法是确定滚动条的宽度,并使用 calc()100vw减少滚动条的数量。这有点复杂,因为在我的例子中,我是从一个定义了边距的框中提取内容的宽度,所以我也需要声明边距。

关于下面的代码有一些注意事项: 首先,我注意到20px 对于滚动条来说似乎是一个相当宽泛的神奇数字。我使用一个 SCSS 变量(它不一定是 SCSS)和 @supports之外的代码作为备用。

此外,这不 保证将永远不会有滚动条。因为它需要 Javascript,没有启用的用户将看到水平滚动条。您可以通过设置 overflow-x: hidden,然后添加一个类在 Javascript 运行时覆盖它来解决这个问题。

完整 SCSS 密码:

$scroll-bar: 20px;


:root {
--scroll-bar: 8px;
}


.screen-width {
width: 100vw;
margin: 0 calc(-50vw + 50%);


.has-scrollbar & {
width: calc(100vw - #{$scroll-bar});
margin: 0 calc(-50vw + 50% + #{$scroll-bar / 2});
}


@supports (color: var(--scroll-bar)) {
.has-scrollbar & {
width: calc(100vw - var(--scroll-bar));
margin: 0 calc(-50vw + 50% + (var(--scroll-bar) / 2));
}
}
}

只需删除 #{$scroll-bar}引用并替换为 px 值,就可以将上面的代码转换为纯 CSS

然后这个 Javascript 将设置 CSS 自定义属性:

function handleWindow() {
var body = document.querySelector('body');


if (window.innerWidth > body.clientWidth + 5) {
body.classList.add('has-scrollbar');
body.setAttribute('style', '--scroll-bar: ' + (window.innerWidth - body.clientWidth) + 'px');
} else {
body.classList.remove('has-scrollbar');
}
}


handleWindow();

顺便说一句,Mac 用户可以通过进入系统偏好设置-> 常规-> 显示滚动条 = 总是来测试这一点

下面是我对100vw 添加水平滚动条的解决方案:

html {
width: calc(100% + calc(100vw - 100%));
overflow-x: hidden;
}


.box {
width: calc(100% + calc(100vw - 100%));
}

我也在为此苦苦挣扎,我还考虑了 CSS 变量作为解决方案。在 IE11中不支持 CSS 变量,所以我尝试了其他方法:

我通过计算滚动条的宽度来修正它: 从 window的宽度(包括滚动条)中减去 body的宽度(不包括滚动条)。我使用这个把它添加到100% 的身体,参见 plusScrollBar变量。

约翰逊:

    // calculate width of scrollbar and add it as inline-style to the body
var checkScrollBars = function() {
var b = $('body');
var normalw = 0;
var scrollw = 0;
normalw = window.innerWidth;
scrollw = normalw - b.width();


var plusScrollBar = 'calc(' + '100% + ' + scrollw + 'px)'
document.querySelector('body').style.minWidth = plusScrollBar;
}();

CSS:

html{
overflow-x: hidden;
}

为什么我喜欢这个: 它考虑到并不是所有的滚动条都是相同的宽度或者被认为是守恒的空间。:)

我也有同样的问题,当我加上:

html, body { overflow-y: auto; }

我加了一条评论:

/* this fixes a 100vw issue, removing the horizontal scrollbar when it's unneeded */

它至少可以在火狐、 Chrome、 Opera 和 Internet Explorer 11下工作(我用的是 IE 浏览器)。

我不知道它为什么有效,是否在所有情况下都有效。

编辑: 水平滚动条消失了,但我注意到它仍然是水平滚动使用光标键和触摸屏..。

我也遇到了同样的问题,当我将大众单位改为百分比时,水平滚动条消失了。

使用 max-width属性和 width:100vw属性,解决了我的问题。

这是我用过的。

.full{
height: 100vh;
width: 100vw;
max-width: 100%;
}

基本上它所做的就是固定视窗的最大宽度,这样水平滚动就消失了。

更多@https://www.w3schools.com/cssref/pr_dim_max-width.asp

Max-width 属性定义元素的最大宽度。

如果内容大于最大宽度,它将自动 改变元素的高度。

如果内容小于最大宽度,则为最大宽度 财产没有效力。

如果您在一个框架(例如 ASP.NET)中工作,其中可能有一个父元素环绕着 html,那么将 html 的 max-width设置为100% 就可以解决这个问题,而不需要使用“创可贴”解决方案 overflow-x: hidden

html {
max-width: 100%;
}

overflow-x: clip;完成任务。