当垂直滚动条出现时,如何阻止我的网页内容左移?总结2017年的建议 [英] How Do I Stop My Web Content From Shifting Left When The Vertical Scrollbar Appears? Roll-Up of Advice 2017

查看:106
本文介绍了当垂直滚动条出现时,如何阻止我的网页内容左移?总结2017年的建议的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

许多程序员已经询问如何停止他们的网页内容 - —尤其是以它们为中心的网页内容( margin:0 auto; )—从垂直滚动条出现时水平移动(被推动) 这对Ajax用户和像我这样的人使用隐藏的div和制表符来组织数据一直是一个问题。



当当前显示的页面发生变化时,显示的材料的高度(内部窗口高度)突然大于物理窗口高度时出现问题。



所有滚动条的创建都不相同的现实加剧了这个问题 不同的浏览器给它们的滚动条不同的宽度,并且这个差别不能被预测(或者至少不应该)被预测。解决方案是独立于滚动条宽度的。



因此,这是一个自我回答的问题,它将所有这些答案与我的解决方案及其有用性到2017年8月5日为止的单个答案。 我已经标记为与以前的许多问题重复,因为我可以fi以便人们可以对此问题进行全面讨论。



请注意,此答案解决了BODY内容转移问题。 如果您有DIV在固定的高度存在移位问题时,应该将DIV宽度设置为固定宽度( px )宽度,以便其滚动条浮动在文本上方并添加一些右侧填充不要让文字掉下来。贡献者: Hashbrown
Avrahamcool
爱德华纽索姆

解决方案

在进入单个解决方案之前,应该提到它们分为三类:CSS-,CSS3-和基于Javascript的解决方案。



CSS解决方案通常会相互融合,但非常可预测并得到很好的支持。 CSS3解决方案具有像Javascript这样的CPU计算成本,但易于实现。然而,在2017年以前的几年中,它们在浏览器中有零星支持。 随着时间的推移,它正在得到改进。 最终, y可能是最好的解决方案,但我今天的调查显示,这种支持还不够完善,此外,传统的浏览器支持是不存在的。 > Javascript解决方案(无论是直接使用Javascript还是使用jQuery)都需要额外的编码来使它们更加健壮,因为它们没有固有的支持(例如)窗口大小调整。 然而,它们仍然是最可预测和最向后兼容的保留页面的美感 我认为传统浏览器的界限是介于IE6和IE7之间&&老实说,我对任何仍然使用旧浏览器的人表示哀悼。



请注意,我 没有包含以前发布到Stack Exchange的每个CSS3和Javascript解决方案。 有些虽然新颖但有很大缺陷,因此未包含在内在这里。
$ b



解决方案1:CSS解决方案



贡献者: Hive7 koningdavid Christofer Eliasson 电唱峡谷 Shawn Taylor mVChr fsn Damb ,< a href =https://stackoverflow.com/questions/5605667/scrollbar-shifts-content/5605792#5605792> Sparky , Michael Krelin - 黑客 Melvin Guerrero



强制滚动条始终打开。

 < style> 
html {
overflow-y:scroll;
}
< / style>

此解决方案基本保证始终有效(有一些例外情况,但非常少见) ,但它在美学上不令人满意。 滚动条总是被看到,无论是否需要。 虽然共识是在 html 标签中使用这个解决方案,人们建议在 body 标记中使用它。



结果



微软(IE10 +)已经实现了浮动滚动条,这意味着你的页面可能不像其他浏览器那样居中。 然而,这似乎是一个非常小的问题。



使用像FancyBox,Flex-Box或Twitter Bootstrap Modal这样的结构化接口时,当这些接口创建自己的滚动条时,会出现双滚动条。



程序员应避免使用 overflow:scroll ,因为这会导致垂直和水平滚动条出现。



解决方案#1a:替代方案

贡献者: koningdavid



一个聪明的选择,但只有一个小的美学差异,是做这个:

 < style> 
html {
height:101%;
}
< / style>

这会激活滚动条背景,但不会激活滚动条 除非垂直内容实际上溢出了窗口的底部边缘然而,它具有相同的缺点,即无论是否需要,滚动条空间都会被永久使用。 b

解决方案#1b:更现代的解决方案
$ b 贡献者:
凯尔杜莫维奇 SimonDos



浏览器开始使用滚动条的 overlay 值,模仿IE10 +的浮动滚动条。

 < style> 
html {
overflow-y:overlay;
}
< / style>

此解决方案模仿IE10 +中的浮动滚动条,但它尚未在所有浏览器中使用,一些实现怪癖 这种解决方案已知不适用于像Bootstrap Modal这样的基础架构环境。



解决方案2: CSS3解决方案



使用CSS3来计算宽度 有很多方法可以做到这一点,每种方法都有其优点和缺点。 (a)不知道实际的滚动条宽度,(b)处理屏幕大小调整,以及(c)CSS正在慢慢变成另一种完全功能的编程语言 - 像Javascript—但它还没有完全演变成这样的一种情况。它是否有意义成为这样的问题还有另一个问题的争论。


<用户可能会禁用Javascript,所以只能使用CSS的解决方案的说法更可取,因为它变得无关紧要。 客户端编程变得如此无处不在,以至于只有最偏执狂的人仍然在禁用Javascript。 个人而言,我没有请注意,有些解决方案会修改保证金

c>和其他修改 padding 。 那些修改 margin 的常见问题是:如果您有导航栏,标题,边框等等,这些解决方案将使用与页面背景不同的颜色,从而暴露出不合需要的边框。 很可能任何使用 margin 的解决方案都可以重新设计使用 padding ,反之亦然。

解决方案# 2a:基于HTML的解决方案
$ b 贡献者:
半透明云 Mihail Malostanidis

 < style> 
html {
margin-left:calc(100vw - 100%);
margin-right:0;
}
< / script>

解决方案#2b:基于BODY的解决方案



贡献者: Greg St.Onge Moesio 乔纳森SI

 < style> 
body {
padding-left:17px;
width:calc(100vw - 17px);
}
@media screen and(min-width:1058px){
body {
padding-left:17px;
width:calc(100vw - 17px);
}
}
< / style>

100vw 是视口宽度的100% 。

结果



有些用户提出这个解决方案时会产生不希望的屏幕噪音该窗口的大小会调整(可能计算过程在调整大小的过程中会出现多次) 一种可能的解决方法是避免使用 margin:0 auto; 来居中放置内容而是使用以下代码(示例中显示的 1000px 500px 代表您的内容最大宽度和一半的数量,分别):

 < style> 
body {
margin-left:calc(50vw - 500px);
}
@media screen和(max-width:1000px){
body {
margin-left:0;
}
}
< / style>

这是一个固定滚动条宽度的解决方案,它不是独立于浏览器的。它与浏览器无关,必须包含Javascript来确定滚动条的宽度。 一个计算宽度但不重新包含该值的示例是:

请注意下面的代码片段已经在Stack Exchange和互联网上的其他位置多次发布,没有明确的归属。

  function scrollbarWidth(){
var div = $('< div style =width:50px; height:50px; overflow:hidden; position:absolute; top:-200px; left :-200px;>< div style =height:100px;>< / div>');
//追加我们的div,做我们的计算,然后删除它
$('body')。append(div);
var w1 = $('div',div).innerWidth();
div.css('overflow-y','scroll');
var w2 = $('div',div).innerWidth();
$(div).remove();
return(w1 - w2);
}

解决方案#2c:基于DIV的解决方案

贡献者:



使用直接应用于容器DIV元素的CSS3计算。

 < body> 
< div style =padding-left:calc(100vw - 100%);>
我的内容
< / div>
< / body>

结果



<与所有的CSS3解决方案一样,这并不是所有的浏览器都支持的。 即使那些支持视口计算的浏览器也不支持(截至撰写本文时)任意使用它。



解决方案#2d:Bootstrap模式

贡献者: Mihail Malostanidis kashesandr

Twitter Bootstrap Modal的用户发现将以下CSS3应用到他们的HTML元素是有用的。

 < style> 
html {
width:100%;
宽度:100vw;
}
< / style>

另一个建议是围绕您的内容包装器创建一个包装器,该包装器用于自动检测

 < style> 
body {
overflow-x:hidden;
}
#wrap-wrap {
width:100vw;
}
#content-wrap {
margin:0 auto;
width:800px;
}
< / style>

我没有试过其中任何一个,因为我没有使用Bootstrap。




解决方案3:Javascript解决方案

贡献者:< a href =https://stackoverflow.com/questions/5605667/scrollbar-shifts-content/5605759#5605759>山姆, JBH



这是我最喜欢的解决方案,它处理所有问题,并且与传统浏览器相当兼容。最棒的是,它是独立于滚动条宽度的。

 < script> 
函数updateWindow(){
document.body.style.paddingLeft =(window.innerWidth - document.body.clientWidth);
document.body.onclick = function(){
document.body.style.paddingLeft =(window.innerWidth - document.body.clientWidth);
}
}
window.onload = updateWindow();
window.addEventListener(resize,updateWindow());
updateWindow();
< / script>

结果



对于 updateWindow(); 的最终命令应该在< / body> 标记之前出现以避免问题动态加载的内容,例如Facebook Like-Boxes。 似乎它对于 window.onload 事件是多余的,但不是每个浏览器都会将 onload >



这个函数每次都执行用户在网页中点击的时间 感谢的是,现代电脑的速度足够快,这不是什么大问题。  Still…。
$ b

最后,在任何div异步更新(AJAX)之后,该函数应该被执行。 在这个例子中没有显示,但是它将成为就绪状态的一部分。 例如:

  xmlhttp.onreadystatechange = function(){
if(xmlhttp.readyState == 4&& xml http.status == 200){
if(xmlhttp.responseText =='false'){
//在这里处理错误
} else {
//成功处理
updateWindow();
}
}
}

解决方案#3a :测量滚动条宽度

贡献者: Lwyrn



这是一个不太有价值的解决方案,需要花时间来测量滚动条宽度。

 < script> 
var checkScrollBars = function(){
var b = $('body');
var normalw = 0;
var scrollw = 0;
if(b.prop('scrollHeight')> b.height()){
normalw = window.innerWidth;
scrollw = normalw - b.width();
$('#container')。css({marginRight:' - '+ scrollw +'px'});
}
}
< / script>
< style>
body {
overflow-x:hidden;
}
< / style>

结果



<与其他解决方案一样,这个永久禁用水平滚动条。


Many programmers have asked how to stop their web page content — especially their centered web page content (margin: 0 auto;) — from shifting (being pushed) horizontally when the vertical scroll bar appears. This has been an ongoing problem for Ajax users and people like me who use hidden divs and tabs to organize data.

The problem occurs when the currently displayed page changes such that the height of the displayed material (the inner window height) is suddenly greater than the physical window height.

The problem is exacerbated by the reality that all scrollbars are not created equal. Different browsers give their scroll bars different widths, and that difference cannot (or, at least, should not) be predicted. In short, the ideal solution is scrollbar width independent.

This, therefore, is a self-answered question that rolls all those answers with commentary on their usefullness (where possible) along with my own solution into a single answer as of August 5, 2017. I've marked as duplicates as many of the previous questions as I can find so that people can find a comprehensive discussion of the issue.

Please note that this answer addresses problems with BODY contents shifting. If you have a DIV with a fixed height that has shifting problems, you should set the DIV width to a fixed (px) width so its scrollbar floats above the text and add some right-hand padding to keep the text from falling beneath it. Contributors: Hashbrown, Avrahamcool, Edward Newsome

解决方案

Before going into individual solutions, it should be mentioned that they break down into three categories: CSS-, CSS3-, and Javascript-based solutions.

The CSS solutions tend to be ridged but very predictable and very well supported.

The CSS3 solutions have a CPU calculation cost like Javascript, but are easy to implement. In years previous to 2017, however, they had sporadic support in browsers. That is improving over time. Ultimately, they will likely be the best solution, but my own investigations today have demonstrated the support simply isn't consistent enough yet and, besides, legacy browser support is non-existent.

The Javascript solutions (whether in straight Javascript or in jQuery) need extra coding to make them robust as they have no intrinsic support for (e.g.) window resizing. However, they're the most predictable and the most backward compatible while still preserving the aesthetics of the page. I consider the line for legacy browsers to be between IE6 and IE7. Frankly, my condolences to anyone still using a browser that old.

Please note that I have not included every CSS3 and Javascript solution previously posted to Stack Exchange. Some, though novel, had substantial weaknesses and so were not included here.


Solution #1: The CSS Solution

Contributors: Hive7, koningdavid, Christofer Eliasson, Alec Gorge, Scott Bartell, Shawn Taylor, mVChr, fsn, Damb, Sparky, Ruben, Michael Krelin - hacker, Melvin Guerrero

Force the srollbar to always be on.

<style>
html {
    overflow-y: scroll;
}
</style>

This solution is basically guaranteed to always work (there are some exceptions, but they're very rare), but it is aesthetically unpleasing. The scrollbar will always be seen, whether it's needed or not. While concensus is to use this solution in the html tag, some people suggest using it in the body tag.

Consequences

Microsoft (IE10+) has implented floating scroll bars which means your page may not be centered in it like it would be in other browsers. However, this seems to be a very minor issue.

When using structured interfaces like FancyBox, Flex-Box, or Twitter Bootstrap Modal this can cause a double-scrollbar to appear as those interfaces create their own scrollbars.

Programmers should avoid using overflow: scroll as this will cause both the vertical and horizontal scrollbars to appear.

Solution #1a: An Alternative

Contributors: koningdavid, Nikunj Madhogaria

A clever alternative, but one having only a minor aesthetic difference, is to do this:

<style>
html {
    height: 101%;
}
</style>

This activates the scroll bar background but doesn't activate the scroll bar tab unless your vertical content actually overflows the bottom edge of the window. Nevertheless, it has the same weakness in that the scrollbar space is permanently consumed whether needed or not.

Solution #1b: A More Modern Solution

Contributors: Kyle Dumovic, SimonDos

Browsers are beginning to pick up the use of the overlay value for scrollbars, mimicking the floating scrollbar of IE10+.

<style>
html {
    overflow-y: overlay;
}
</style>

This solution mimics the floating scrollbar in IE10+, but it is not yet available in all browsers and still has some implementation quirks. This solution is known not to work for infrastructure environments like Bootstrap Modal.


Solution #2: The CSS3 Solution

Use CSS3 to calculate widths. There are many ways to do this with advantages and disadvantages to each. Most disadvantages are due to (a) not knowing the actual scrollbar width, (b) dealing with screen resizing, and (c) the fact that CSS is slowly becoming yet-another-fully-functioning-programming language — like Javascript — but has not yet completely evolved into such. Whether or not it even makes sense for it to become such is a debate for another question.

The argument that users may disable Javascript and so a CSS-only solution is preferable is becoming irrelevant. Client-side programming has become so ubiquitous that only the most paranoid of people are still disabling Javascript. Personally, I no longer consider this a tenable argument.

It should be noted that some solutions modify margin and others modify padding. Those that modify margin have a common problem: if you have navigation bars, headers, borders, etc. that use a different color than the page background this solution will expose undesirable borders. It is likely that any solution using margin can be re-designed to use padding and vice-versa.

Solution #2a: The HTML-based Solution

Contributors: TranslucentCloud, Mihail Malostanidis

<style>
html {
    margin-left: calc(100vw - 100%);
    margin-right: 0;
}
</script>

Solution #2b: The BODY-based Solution

Contributors: Greg St.Onge, Moesio, Jonathan SI

<style>
body {
    padding-left: 17px;
    width: calc(100vw - 17px);
}
@media screen and (min-width: 1058px) {
    body {
        padding-left: 17px;
        width: calc(100vw - 17px);
    }
}
</style>

100vw is 100% of the viewport width.

Consequences

Some users have suggested this solution creates undesirable screen noise when the window is resized (perhaps the calculation process is occuring multiple times during the resize process). A possible workaround is to avoid using margin: 0 auto; to center your content and instead use the following (the 1000px and 500px shown in the example represent your content maximum width and half that amount, respectively):

<style>
body {
    margin-left: calc(50vw - 500px);
}
@media screen and (max-width: 1000px) {
    body {
        margin-left: 0;
    }
}
</style>

This is a fixed-scrollbar-width solution, which isn't browser independent. To make it browser independent, you must include Javascript to determine the width of the scrollbars. An example that calculates the width but does not re-incorporate the value is:

Please note that the code snippet below has been posted multiple times on Stack Exchange and other locations on the Internet verbatim with no firm attribution.

function scrollbarWidth() {
    var div = $('<div style="width:50px;height:50px;overflow:hidden;position:absolute;top:-200px;left:-200px;"><div style="height:100px;"></div>');
    // Append our div, do our calculation and then remove it
    $('body').append(div);
    var w1 = $('div', div).innerWidth();
    div.css('overflow-y', 'scroll');
    var w2 = $('div', div).innerWidth();
    $(div).remove();
    return (w1 - w2);
}

Solution #2c: The DIV-based Solution

Contributors: Rapti

Use CSS3 calculations applied directly to a container DIV element.

<body>
    <div style="padding-left: calc(100vw - 100%);">
    My Content
    </div>
</body>

Consequences

Like all CSS3 solutions, this is not supported by all browsers. Even those browsers that support viewport calculations do not (as of the date of this writing) support its use arbitrarily.

Solution #2d: Bootstrap Modal

Contributors: Mihail Malostanidis, kashesandr

Users of Twitter Bootstrap Modal have found it useful to apply the following CSS3 to their HTML element.

<style>
html {
    width: 100%;
    width: 100vw;
}
</style>

Another suggestion is to create a wrapper around your content wrapper that is used to auto-detect changes in the viewport width.

<style>
body {
    overflow-x: hidden;
}
#wrap-wrap {
    width: 100vw;
}
#content-wrap {
    margin: 0 auto;
    width: 800px;
}
</style>

I have not tried either of these as I do not use Bootstrap.


Solution #3: The Javascript Solution

Contributors: Sam, JBH

This is my favorite solution as it deals with all the issues and is reasonably backward compatible to legacy browsers. Best of all, it's scrollbar-width independent.

<script>
function updateWindow(){
    document.body.style.paddingLeft = (window.innerWidth - document.body.clientWidth);
    document.body.onclick=function(){
            document.body.style.paddingLeft = (window.innerWidth - document.body.clientWidth);
    }
}
window.onload=updateWindow();
window.addEventListener("resize", updateWindow());
updateWindow();
</script>

Consequences

The final command to updateWindow(); should occur just before the </body> tag to avoid problems with dynamically-loaded content such as Facebook Like-Boxes. It would seem that it's redundant to the window.onload event, but not every browser treats onload the same way. Some wait for asynchronous events. Others don't.

The function is executed each and every time a user clicks within the web page. Gratefully, modern computers are fast enough that this isn't much of an issue. Still….

Finally, the function should be executed after any div is asynchronously updated (AJAX). That is not shown in this example, but would be part of the ready-state condition. For example:

xmlhttp.onreadystatechange=function(){
    if(xmlhttp.readyState==4 && xmlhttp.status==200){
        if(xmlhttp.responseText == 'false'){
            //Error processing here
        } else {
            //Success processing here
            updateWindow();
        }
    }
}

Solution #3a: Measuring Scrollbar Widths

Contributors: Lwyrn

This is a less valuable solution that takes the time to measure scrollbar widths.

<script>
var checkScrollBars = function(){
    var b = $('body');
    var normalw = 0;
    var scrollw = 0;
    if(b.prop('scrollHeight')>b.height()){
        normalw = window.innerWidth;
        scrollw = normalw - b.width();
        $('#container').css({marginRight:'-'+scrollw+'px'});
    }
}
</script>
<style>
body {
    overflow-x: hidden;
}
</style>

Consequences

Like other solutions, this one permanently disables the horizontal scrollbar.

这篇关于当垂直滚动条出现时,如何阻止我的网页内容左移?总结2017年的建议的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆