防止100vw创建水平滚动

时间:2015-05-27 17:45:04

标签: css css3 scroll

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

有可能阻止这种情况吗?

是否可以在不禁用整个页面的水平滚动的情况下阻止此操作?除了改变我的css / markup以使元素100%的宽度,我无法想到任何事情。

在Chrome版本43.0.2357.81 m& FF 36.0.1& Windows 8.1上的Opera 20.0.1387.91

以下是所要求的代码:

Example

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

15 个答案:

答案 0 :(得分:27)

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

警告: 我尚未针对浏览器支持测试这些解决方案

<强> TL;博士

如果您需要一个元素为可见视口的100%宽度(视口减去滚动条),则需要将其设置为正文的100%。如果有垂直滚动条,则无法使用vw单位。

<强> 1。将所有祖先元素设置为静态位置

如果您确保所有.box的祖先都设置为position: static;,那么请将.box设置为width: 100%;,这样它将是身体宽度的100%。但这并不总是可行的。有时您需要其中一个祖先为position: absolute;position: relative;

launch modes

<强> 2。将元素移到非静态祖先之外

如果您无法将祖先元素设置为position: static;,则需要将.box移到它们之外。这将允许您将元素设置为体宽的100%。

Example

第3。删除垂直滚动条

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

Example

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

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

Example

视口 - 百分比长度规格

  

视口百分比长度是相对于的大小   初始包含块。当初始的高度或宽度   包含块被更改,它们会相应缩放。然而,   当根元素上的溢出值为auto时,任何滚动   假设条不存在。注意初始包含   块的大小受到滚动条的存在的影响   视口。

似乎存在一个错误,因为当根元素上的溢出设置为auto时,vw单元应仅包含滚动条宽度。但我已经尝试将根元素设置为overflow: scroll;并且它没有改变。

Example

答案 1 :(得分:6)

我知道这是一个老问题,但这个错误仍然存​​在于现代浏览器中。我不喜欢做overflow-x: hidden的想法,所以这就是我所做的。这里有一个完整的例子:http://codepen.io/bassplayer7/pen/egZKpm

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

关于以下代码的一些注意事项:首先,我注意到20px似乎是滚动条的相当宽的幻数。我使用SCSS变量(它不一定是SCSS)和@supports之外的代码作为后备。

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

完整代码:

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

然后这个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用户可以通过转到系统偏好设置 - &gt;进行测试。一般 - &gt;显示滚动条=始终

答案 2 :(得分:2)

填充和边框可能会干扰。保证金也可以。使用box-sizing计算宽度,包括这些属性。并且可以从宽度中删除边距(如果有的话)。

* {
    -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,IE 11 Metro)的浏览器中似乎没有这种情况,但可能会影响所有其他浏览器。

答案 3 :(得分:1)

这是我对100vw添加水平滚动问题的解决方案:

def send_activation_email(self):
    subject = 'SUBJECT'
    message = 'MESSAGE'
    from_email = settings.EMAIL_ADRESS
    to_email = self.email
    send_mail(
        subject,
        message,
        from_email,
        [to_email],
        fail_silently=False,
    )

答案 4 :(得分:1)

我也在努力解决这个问题,我也将CSS变量视为解决方案。 IE11中不支持CSS变量,所以我尝试了其他的东西:

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

JS:

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

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

答案 5 :(得分:0)

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

答案 6 :(得分:0)

max-width属性与width:100vw一起使用可以解决我的问题。

这就是我用的。

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

基本上,它是将最大宽度固定到视口,从而消除了水平滚动。

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

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

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

如果内容小于最大宽度,则为最大宽度 属性无效。

答案 7 :(得分:0)

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

html {
   max-width: 100%;
}

答案 8 :(得分:0)

这是一个 JS 解决方案,它将主体的宽度传递给您给定类 width-full 的元素。如果您的 body 宽度为 100%

function setToBodyWidth() {
  const elements = document.querySelectorAll('.width-full');
  elements.forEach( element => {
    element.style.width = document.body.offsetWidth + 0.9 + 'px'; // note the .9 added here. 
  });
}

// Call the function
setToBodyWidth();

// Call the function whenever the window is resized. 
window.addEventListener("resize", function() {
  setToBodyWidth();
});

添加的 0.9 像素可解决舍入问题,而无需添加水平滚动。如果不考虑它,在某些尺寸下,您可能会发现组件左侧显示一条宽度为单个像素的白线。

答案 9 :(得分:-1)

这就是我的所作所为:

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

}

答案 10 :(得分:-1)

我通过在相关页面添加正文{overflow-x:hidden}来修复此问题。

也适用于你的例子。

答案 11 :(得分:-1)

好吧。我知道我迟到了。

但是这是我需要100vw的所有页面上使用的解决方案: 不要显示垂直滚动条。

无论如何,删除滚动条看起来都更好。至少在我看来。

这是您的工作:

::-webkit-scrollbar {
  width: 0px;
}

有你去

答案 12 :(得分:-1)

我有同样的问题,添加时已解决:

response_bytes = response_bytes_io.read()
if response_bytes.startswith(b'\xef\xbb\xbf'):
    response_bytes = response_bytes[3:]
parser = etree.XMLParser(encoding='utf-8')
xml = etree.parse(source=io.BytesIO(response_bytes), parser=parser)

我添加了评论:

html, body { overflow-y: auto; }

它至少与Firefox,Chrome,Opera和Internet Explorer 11(我使用IE的浏览器)兼容。

我不知道它为什么起作用,以及在所有情况下它是否都能起作用。

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

答案 13 :(得分:-1)

很惊讶这个答案不在这里。我总是执行以下操作,这似乎很有效。

width: calc(100vw - (100vw - 100%))

100vw - 100% 获取页面上任何垂直滚动条的宽度,我们只需从 100vw 中减去该宽度即可获得我们想要的实际视口宽度。

答案 14 :(得分:-2)

width: 100vw元素只有当其中一个父元素具有水平填充时才会导致水平滚动条。否则它应该很好。

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

修改

在你的情况下,我猜你的body有余量。请检查此代码并尝试删除正文css规则:http://jsfiddle.net/1jh1cybc/1/