如何防止滚动条重新定位网页?


218

我有一个中心对齐的DIV网站。现在,有些页面需要滚动,有些不需要。当我从一种类型移动到另一种类型时,滚动条的外观会将页面向侧面移动几个像素。如果没有在每个页面上明确显示滚动条,有什么办法可以避免这种情况?


6
为什么没有人overflow-y: overlay在此线程中提及?
milkersarac

3
根据mozilla docs的意见,overflow-y: overlay其折旧价格为:developer.mozilla.org/en-US/docs/Web/CSS/overflow
drojf

Answers:


266

overflow-y:scroll是正确的,但是您应该将其与html标记一起使用,而不是body,否则在IE 7中会得到一个双滚动条,
因此正确的CSS应该是:

html {
  overflow-y: scroll;
}

1
IE 10+具有浮动滚动条,因此您应为这些浏览器禁用此滚动条
Ruben 2014年

1
当与fancybox或twitter引导程序模式结合使用时,这可能会导致类似双滚动条的问题
Ruben 2014年

额外的信息:当模态打开时,twitter bootstrap现在会向您的身体添加.modal-open
Ruben

55
值得一提的是,它永久显示一个垂直滚动条。可能并不总是可以接受的。
rustyx

我在Chromium和Firefox中都有一个双滚动条。我正在使用flex-box; 也许是造成这种情况的原因
Garrett

72

将可滚动元素的内容包装到div中并应用padding-left: calc(100vw - 100%);

<body>
    <div style="padding-left: calc(100vw - 100%);">
        Some Content that is higher than the user's screen
    </div>
</body>

诀窍是100vw代表包括滚动条在内的100%视口。如果减去100%,这是没有滚动条的可用空间,则最终会导致滚动条的宽度增大或者宽度0不存在。在左侧创建该宽度的填充将模拟第二个滚动条,将居中的内容移回右侧。

请注意,这仅在可滚动元素使用页面的整个宽度时才有效,但是在大多数情况下这应该没有问题,因为在其他情况下,以可滚动内容为中心的情况很少。


1
通过类比内联样式更好地应用,并且只能在这些浏览器中使用,但这是一个聪明的技术-我没有意识到这一点,100vw并且没有100%测量不同的东西,因此我从中学到了一些有用的东西!
尼克F

21
考虑到浏览器对calc的支持非常好,这绝对是个天才,确实是最好的答案。
迈克尔

1
您可以执行相同的操作,除了在左边添加负边距而不是在左边添加边距(请参见stackoverflow.com/a/39289453/6015444)。
Touniouk '18

2
此解决方案将导致类似的背景色问题,如答案“ width:calc(100vw-34px);”。但在左侧。
Maciej Lew

1
我建议向此样式添加一些媒体查询@media screen and (min-width: 800px) {...} 。如果内容适合页面宽度。例如,在较小的分辨率上,会出现不必要的间隙,将内容向右移动
MarkosyanArtur

44

我觉得不是。但是造型bodyoverflow: scroll应该做的。不过,您似乎知道这一点。


3
听起来不错...强制页面始终显示滚动条是否需要它,...然后页面类型之间没有视觉变化。
eidylon

1
是的,但是IIRC,它显示了两个滚动条。我真的不需要水平的。
Dmitri Nesteruk 09年

确实如此。但没有多少,我可以做些什么来帮助你:(其实,我只考虑我的回答的第一句话是真正的答案与问题的交易。
迈克尔Krelin -黑客

49
overflow-y: scroll:)
Svish

2
以下是更好的答案
Sami 2012年

36

总是显示滚动条,可能不利于布局。

尝试使用CSS3限制车身宽度

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

vw是视口的宽度(请参阅此链接的一些解释)
calc计算CSS3
34px代表双滚动条的宽度(见固定或此计算,如果你不信任固定大小)


4
除非有人需要,否则一切都是徒劳的。
Moesio 2015年

3
从视觉上讲,这不像像已接受的答案所描述的那样强迫scollbars那样容易。
西拉斯·汉森

4
到目前为止,这已经最适合我的需求,我还添加padding-left: 34px;了平均居中的页面。
Pat Migliaccio

3
这应该是可接受的答案,与当前接受的答案不同,它实际上是在回答问题!
Coz

2
这会导致一些问题,如果你有不同的颜色比身体背景或底部边框等导航栏/头
齐亚。拉赫曼莫卧儿

28
html {
  overflow-x: hidden;
  margin-right: calc(-1 * (100vw - 100%));
}

实例。单击“更改最小高度”按钮。

使用calc(100vw - 100%)我们可以计算滚动条的宽度(如果未显示,则为0)。想法:使用负的右边距,我们可以将的宽度<html>增加到该宽度。您将看到一个水平滚动条-应该使用将其隐藏overflow-x: hidden


我不得不将身体放在一个div中,然后在div上应用边距才能使其正常工作(类似于Rapti的回答。)但是,这看起来太整齐了。
Touniouk '18

1
这很好用,似乎不会在Chrome或Firefox中导致不必要的水平滚动条。为什么不只是使用calc(100% - 100vw)而不是乘以-1
SystemParadox

13

我不知道这是否是旧帖子,但是我遇到了同样的问题,如果您只想垂直滚动,则应该尝试 overflow-y:scroll


13

如果更改大小或在加载一些数据后添加滚动条,则可以尝试跟随,创建类并应用该类。

.auto-scroll {
   overflow-y: overlay;
   overflow-x: overlay;
}

3

通过在视口大小减去滚动条的宽度中显式设置javascript主体的宽度,我已经在我的一个网站上解决了该问题。我使用此处记录的基于jQuery的函数来确定滚动条的宽度。

<body id="bodyid>

var bodyid = document.getElementById('bodyid');
bodyid.style.width = window.innerWidth - scrollbarWidth() + "px";

10
我什至无法开始解释为什么这是一种不好的做法。
mythofechelon,2012年

20
@BenHooper:我想知道为什么这是不好的做法。
2013年

1
如果调整窗口大小会怎样?
Braden Steffaniak

3

使用以下方法扩展答案:

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

一位评论者建议也添加左填充以保持居中:

body {
    padding-left: 17px;
    width: calc(100vw - 17px);
}

但是,如果您的内容比视口宽,那么看起来就不正确。要解决此问题,您可以使用媒体查询,如下所示:

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

其中1058px =内容宽度+ 17 * 2

这样,当视口足够宽以包含固定宽度的内容时,水平滚动条可以处理x溢出并保持居中的内容居中


3

扩展Rapti的答案,这应该同样有效,但是它在的右侧增加了更多的边距,body并以负的html边距将其隐藏,而不是添加可能会影响页面布局的额外填充。这样,在实际页面上(在大多数情况下)没有任何变化,并且代码仍然可以正常工作。

html {
    margin-right: calc(100% - 100vw);
}
body {
    margin-right: calc(100vw - 100%);
}

我发现在chrome上,这会在我的引导站点上具有垂直滚动条的页面上添加水平滚动。
生姜松鼠

您是否尝试过调查原因?检查元素检查器,查看Bootstrap是否与边距,滚动条或类似内容混淆。
Grant Gryczan

1
引导程序放置在所有内容上的15px的页边距可能与该内容有关,当检查页面时,容器的页边距位于滚动条下方。我申请,overflow-x: hidden并解决了。
生姜松鼠

3

@kashesandr的解决方案对我有用,但是为了隐藏水平滚动条,我为主体添加了另一种样式。这是完整的解决方案:

的CSS

<style>
/* prevent layout shifting and hide horizontal scroll */
html {
  width: 100vw;
}
body {
  overflow-x: hidden;
}
</style>

JS

$(function(){
    /**
     * For multiple modals.
     * Enables scrolling of 1st modal when 2nd modal is closed.
     */
    $('.modal').on('hidden.bs.modal', function (event) {
      if ($('.modal:visible').length) {
        $('body').addClass('modal-open');
      }
    });
});

JS Only解决方案(从第一个模态打开第二个模态时):

/**
 * For multiple modals.
 * Enables scrolling of 1st modal when 2nd modal is closed.
 */
$('.modal').on('hidden.bs.modal', function (event) {
  if ($('.modal:visible').length) {
    $('body').addClass('modal-open');
    $('body').css('padding-right', 17);
  }
});

2

我试图解决可能由twitter引导.modal-open类应用于引起的相同问题body。该解决方案html {overflow-y: scroll}无济于事。我发现一种可能的解决方案是将其添加{width: 100%; width: 100vw}html元素中。


1
或将其更改为主体{overflow-y:scroll}
鲁本(Ruben)

1
但这将始终显示滚动条,即使它不是必需的。
拉普蒂

您应该解释为什么要两次设置宽度?html { width: 100vw; }工作对我来说
哈桑塔里克

对我来说,它实际上创建了两个滚动条
rbansal


2

使用calc(100vw-100%)发布的解决方案在正确的轨道上,但是存在一个问题:即使您调整窗口的大小,也将永远在滚动条尺寸的左侧留有边距。内容将填满整个视口。

如果您尝试通过媒体查询解决此问题,则会遇到一个尴尬的捕捉时刻,因为在调整窗口大小时,边距不会逐渐变小。

这是解决该问题的解决方案,并且AFAIK没有缺点:

代替使用margin:自动将内容居中,请使用以下方法:

body {
margin-left: calc(50vw - 500px);
}

将500px替换为内容最大宽度的一半(因此在本示例中,内容最大宽度为1000px)。现在,内容将保持居中边距将一直减小,直到内容填满视口。

为了在视口小于最大宽度时阻止边距变为负数,只需添加媒体查询,如下所示:

@media screen and (max-width:1000px) {
    body {
        margin-left: 0;
    }
}

等等!


2

如果表格的宽度不会改变,则可以设置包含滚动条的元素(例如tbody)的宽度> 100%(为滚动条留出额外的空间),并将overflow-y设置为“ overlay”(覆盖)滚动条保持固定,并且在出现时不会向左移动表格)。还要使用滚动条为元素设置固定的高度,以便一旦超过高度,滚动条就会出现。像这样:

tbody {
  height: 100px;
  overflow-y: overlay;
  width: 105%
}

注意:您必须手动调整宽度%,因为滚动条占用的空间百分比将相对于表格宽度(即:表格宽度较小,需要更大的百分比来容纳滚动条,因为它的像素大小是恒定的) )

一个动态表示例:

function addRow(tableID)
{
    var table = document.getElementById(tableID);
    var rowCount = table.rows.length;
    var row = table.insertRow(rowCount);
    var colCount = table.rows[0].cells.length;
  
    for(var i=0; i<colCount; i++)
    {
        var newRow = row.insertCell(i);

        newRow.innerHTML = table.rows[0].cells[i].innerHTML;
        newRow.childNodes[0].value = "";
    }
}
 
function deleteRow(row)
{
    var table = document.getElementById("data");
    var rowCount = table.rows.length;
    var rowIndex = row.parentNode.parentNode.rowIndex;

    document.getElementById("data").deleteRow(rowIndex);
}
.scroll-table {
  border-collapse: collapse;
}

.scroll-table tbody {
  display:block;
  overflow-y:overlay;
  height:60px;
  width: 105%
}

.scroll-table tbody td {
  color: #333;
  padding: 10px;
  text-shadow: 1px 1px 1px #fff;
}

.scroll-table thead tr {
  display:block;
}

.scroll-table td {
    border-top: thin solid; 
    border-bottom: thin solid;
}

.scroll-table td:first-child {
    border-left: thin solid;
}

.scroll-table td:last-child {
    border-right: thin solid;
}

.scroll-table tr:first-child {
    display: none;
}

.delete_button {
    background-color: red;
    color: white;
}

.container {
  display: inline-block;
}

body {
  text-align: center;
}
<!DOCTYPE html>
<html lang="en">
<head>
  <link rel="stylesheet" href="test_table.css">
</head>

<body>
<h1>Dynamic Table</h1>
<div class="container">

  <table id="data" class="scroll-table">
    <tbody>
      <tr>
        <td><input type="text" /></td>
        <td><input type="text" /></td>
        <td><input type="button" class="delete_button" value="X" onclick="deleteRow(this)"></td>
      </tr>
    </tbody>
  </table>

  <input type="button" value="Add" onclick="addRow('data')" />

</div>

<script src="test_table.js"></script>
</body>
</html>


1

像这样简单地设置容器元素的宽度就可以解决问题

width: 100vw;

这将使该元素忽略滚动条,并且可以使用背景色或图像。



-4
@media screen and (min-width: 1024px){
    body {
    min-height: 700px
    }
}

欢迎使用Stack Overflow!尽管此代码段可以解决问题,但提供说明确实有助于提高您的帖子质量。请记住,您将来会为读者回答这个问题,而这些人可能不知道您提出代码建议的原因。也请尽量不要在代码中加入解释性注释,这会降低代码和解释的可读性!
安德鲁·迈尔斯

-5

与公认的答案相反,即使内容没有溢出屏幕,建议在浏览器窗口上显示一个永久滚动条,我还是喜欢使用:

html{
  height:101%;
}

这是因为如果内容实际溢出,则滚动条的外观更有意义。

更有意义。


1
至少最后一句话是错误的。这与打印机打印的多余空白页相似。
vp_arth '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.