当前位置: 首页 > 知识库问答 >
问题:

当垂直滚动条出现时,如何阻止Web内容左移?2017年建议汇编[副本]

皇甫文乐
2023-03-14

许多程序员都问过,当出现垂直滚动条时,如何阻止他们的网页内容--尤其是居中的网页内容(边距:0 auto;)水平移动(被推)。对于Ajax用户和像我这样使用隐藏div和tab来组织数据的人来说,这一直是一个问题。

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

事实上,所有的滚动条都是不平等的。不同的浏览器给出了不同的滚动条宽度,这种差异无法预测(或者至少不应该预测)。简而言之,理想的解决方案是与滚动条宽度无关。

因此,这是一个自我回答的问题,它将所有这些答案和对其有用性的评论(如果可能的话)以及我自己的解决方案整合成一个单一的答案,截至2017年8月5日。我尽可能多地将以前的问题标记为重复,这样人们就可以找到关于这个问题的全面讨论。

请注意,这个答案解决了正文内容移位的问题。如果您有一个具有固定高度的DIV存在移位问题,您应该将DIV宽度设置为固定的(px)宽度,这样它的滚动条就会浮在文本上方,并添加一些右侧填充以防止文本落到文本下方。撰稿人:Hashbrown,Avrahamcool,Edward Newsome

共有1个答案

申博厚
2023-03-14

在讨论单个解决方案之前,应该提到它们分为三类:CSS-、CSS3-,以及基于JavaScript的解决方案。

CSS解决方案往往是脊状的,但非常可预测,并且得到了很好的支持。

CSS3解决方案和Javascript一样有CPU计算成本,但易于实现。然而,在2017年之前的几年里,它们在浏览器中有零星的支持。随着时间的推移,这种支持正在改善。最终,它们可能是最好的解决方案,但我今天自己的调查表明,支持还不够一致,此外,遗留浏览器支持也不存在。

撰稿人:Hive7、koningdavid、Christofer Eliasson、Alec Gorge、Scott Bartell、Shawn Taylor、mVChr、fsn、Damb、Sparky、Ruben、Michael Krelin-Hacker、Melvin Guerrero

强制滚动条始终处于打开状态。

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

这种解决方案基本上可以保证始终有效(有一些例外,但非常罕见),但它在美学上令人不快。无论是否需要滚动条,滚动条总是会被看到。虽然concensus将在html标记中使用这种解决方案,但有些人建议在body标记中使用它。

后果

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

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

一个聪明的选择,但只有轻微的审美差异,是这样做:

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

这会激活滚动条背景,但不会激活滚动条选项卡,除非垂直内容确实溢出了窗口的底部边缘。然而,它也有同样的缺点,即无论是否需要,滚动条空间都会被永久占用。

解决方案#1B:更现代的解决方案

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

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

用户可能会禁用Javascript,因此只使用CSS的解决方案更好的论点已经变得无关紧要。客户端编程已经变得如此普遍,以至于只有最偏执的人仍然在禁用Javascript。就我个人而言,我不再认为这是一个站得住脚的论点。

需要注意的是,有些解决方案修改边距,另一些解决方案修改边距。那些修改边距的解决方案有一个共同的问题:如果导航条、标题、边框等使用的颜色与页面背景不同,则此解决方案将暴露不需要的边框。任何使用边距的解决方案都可能被重新设计为使用边距,反之亦然。

解决方案#2a:基于HTML的解决方案

撰稿人:TralucentCloud,Mihail Malostanidis

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

解决方案#2B:基于身体的解决方案

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

后果

一些用户建议,当调整窗口大小时,此解决方案会产生不希望的屏幕噪音(可能在调整大小过程中计算过程会发生多次)。一个可能的解决方案是避免使用边距:0 auto;将内容居中,而是使用以下方法(示例中显示的1000px500px分别表示内容的最大宽度和最大宽度的一半):

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

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

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

解决方案#2C:基于div的解决方案

撰稿人:Rapti

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

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

另一个建议是在内容包装器周围创建一个包装器,用于自动检测视口宽度的变化。

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

我没有尝试任何一个,因为我不使用引导。

撰稿人:Sam,JBH

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

updatewindow();的最后一个命令应该出现在标记之前,以避免动态加载的内容(如Facebook like-boxes)出现问题。对于window.onload事件来说,这似乎是多余的,但并不是每个浏览器都以同样的方式对待onload。有些浏览器会等待异步事件,有些则不会。

用户每次点击网页时都会执行该功能。值得庆幸的是,现代计算机速度足够快,这并不是什么问题。尽管如此……。

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

xmlhttp.onreadystatechange=function(){
    if(xmlhttp.readyState==4 && xmlhttp.status==200){
        if(xmlhttp.responseText == 'false'){
            //Error processing here
        } else {
            //Success processing here
            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>
 类似资料:
  • 问题内容: 许多程序员问过如何在出现垂直滚动条时停止其网页内容(尤其是居中的网页内容())在水平方向移动(被推动)。对于Ajax用户和像我这样使用隐藏的div和选项卡来组织数据的人,这一直是一个持续存在的问题。 当当前显示的页面发生更改,使得显示的材料的高度(内部窗口高度)突然大于物理窗口高度时,就会出现问题。 并非所有滚动条都相等的现实使问题更加严重。不同的浏览器为其滚动条提供不同的宽度,并且无

  • 问题内容: 是否可以使用CSS将DIV的垂直滚动条放在div的左侧?那jscript呢? 问题答案: 您可以使用JQuery和此插件在任意位置添加伪滚动条:JScrollPane

  • 我在一个大型遗留系统中工作,系统中有数千个页面,动态生成的表格数据被填充到html中,定义格式如下: 我的任务是移除不必要的小水平滚动条,这些滚动条似乎使系统感到困惑。经过一段时间的研究,我意识到当表格数据量垂直溢出包含的div并导致垂直滚动条出现时,新生成的垂直滚动条本身会推入div的内容区域,从而导致表格数据水平溢出,从而导致不希望出现的水平滚动条。换句话说,当垂直滚动条出现时,它会侵入内容空

  • 我在一个大型遗留系统中工作,系统中有数千个页面,动态生成的表格数据被填充到html中,定义格式如下: 我的任务是移除不必要的小水平滚动条,这些滚动条似乎使系统感到困惑。经过一段时间的研究,我意识到当表格数据量垂直溢出包含的div并导致垂直滚动条出现时,新生成的垂直滚动条本身会推入div的内容区域,从而导致表格数据水平溢出,从而导致不希望出现的水平滚动条。换句话说,当垂直滚动条出现时,它会侵入内容空

  • element-plus的虚拟表格如何让垂直滚动条左移6px? UI要求最后的操作栏,左右间距必须一样,但是由于这个ele的虚拟表格预留了6px的滚动条位置,所以右侧多出6px。这个如何解决呢?研究半天了都不行 从下图可以很清楚的看到这个滚动条宽度是通过js手动设置的

  • 本文向大家介绍JavaScript实现垂直滚动条效果,包括了JavaScript实现垂直滚动条效果的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了js垂直滚动条的实现代码,供大家参考,具体内容如下 1、红色盒子高度计算公式: 容器的高度 / 内容的高度 * 容器的高度 2、红色方块移动一像素 ,我们的内容盒子移动多少呢? (内容盒子高度 - 大盒子高度) / (大盒子高度 - 红色盒