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

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

198614 次浏览

我不这么认为。但是用overflow: scroll样式化body就可以了。不过你好像知道。

我不知道这是否是一个旧帖子,但我有同样的问题,如果你想垂直滚动,你应该尝试overflow-y:scroll

overflow-y:滚动是正确的,但你应该使用它与html标签,而不是身体,否则你会得到一个双滚动条在IE 7
所以正确的css应该是:

html {
overflow-y: scroll;
}

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

<body id="bodyid>


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

滚动总是显示,可能是不好的布局。

尝试使用css3限制主体宽度

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

vw是视口的宽度(详见这个链接 calc计算在css3
34px代表双滚动条宽度(如果不相信固定大小,请参阅这需要计算)

将可滚动元素的内容包装到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(如果它不存在)。在左侧创建该宽度的填充将模拟第二个滚动条,将居中的内容移回右侧。

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

我试图修复可能由推特引导.modal-open类应用于body引起的相同问题。解决方案html {overflow-y: scroll}没有帮助。我发现的一个可能的解决方案是将{width: 100%; width: 100vw}添加到html元素中。

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

html{
height:101%;
}

这是因为如果内容实际上溢出.滚动条的出现更有意义。

更有意义。

我使用一些jquery来解决这个问题

$('html').css({
'overflow-y': 'hidden'
});


$(document).ready(function(){
$(window).load(function() {
$('html').css({
'overflow-y': ''
});
});
});
@media screen and (min-width: 1024px){
body {
min-height: 700px
}
}
html {
overflow-x: hidden;
margin-right: calc(-1 * (100vw - 100%));
}

例子。点击“改变最小高度”按钮。

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

我曾经有过这样的问题,但是解决它的简单方法是这样的(这对我来说很有效):

CSS文件类型:

body{overflow-y:scroll;}

就这么简单!:)

用这个来扩展答案:

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溢出,并在视口足够宽以包含固定宽度的内容时保持居中内容

使用calc(100vw - 100%)发布的解决方案是正确的,但有一个问题:即使你调整了窗口的大小,使内容充满了整个视口,你也将永远有一个滚动条大小的左边边距。

如果你试图用媒体查询来解决这个问题,你会有一个尴尬的瞬间,因为当你调整窗口大小时,边缘不会逐渐变小。

这里有一个解决方案,AFAIK没有任何缺点:

而不是使用margin: auto来居中你的内容,使用这个:

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

将500px替换为内容max-width的一半(所以在这个例子中,内容max-width是1000px)。内容现在将保持居中而且,边距将逐步减少,直到内容填满视口。

为了防止边距在视口小于max-width时变为负值,只需添加一个媒体查询,如下所示:

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

果不其然!

如果改变大小或加载一些数据后,它是添加滚动条,然后你可以尝试以下,创建类和应用这个类。

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

扩展Rapti的回答,这应该也能工作,但它在body的右侧增加了更多的空白,并使用负html空白隐藏它,而不是添加额外的空白,可能会影响页面的布局。这样,实际页面(在大多数情况下)不会发生任何更改,代码仍然具有功能。

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

@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唯一的解决方案(当第二模式从第一模式打开):

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

如果表格的宽度不会改变,你可以设置包含滚动条> 100%的元素(比如tbody)的宽度(允许滚动条的额外空间),并将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>

像这样简单地设置容器元素的宽度就可以了

width: 100vw;

这将使该元素忽略滚动条,并与背景颜色或图像一起工作。

我的方法是使轨道透明。滚动条拇指颜色为#C1C1C1,以匹配默认的滚动条拇指颜色。你可以做任何你喜欢的东西:)

试试这个:

html {
overflow-y: scroll;
}


body::-webkit-scrollbar {
width: 0.7em;
background-color: transparent;
}


body::-webkit-scrollbar-thumb {
background: #C1C1C1;
height:30px;
}


body::-webkit-scrollbar-track-piece
{
display:none;
}

我试过溢出滚动,但它不适合我的情况。滚动条仍然添加了一些(白色)填充。有效的方法是将宽度从100vw更改为100%,但对于高度,可以使用100vh。所以这个:

const Wrapper = styled.div`
min-height: 100vh
`


const Parent = styled.div`
width: 100%
`


const Children = styled.div`
width: 100%
`

<强>编辑 我设置了两次宽度,因为父组件包含侧边栏,而子组件包含侧边栏。根据你的用例,你可以设置它一次

在尝试了以上大多数CSS或基于js的解决方案后,这些解决方案在我的情况下都不起作用,只是想加起来。 我的解决方案适用于滚动条必须在事件中消失的情况(例如,单击按钮,因为你刚刚打开了一个全屏菜单,这应该阻止页面的滚动)

当下面的样式应用于将overflow-y转换为hidden的元素(在我的例子中是body标签)时,这应该是有效的:

body {
overflow-x: hidden;
width: 100vw;
margin-right: calc(100vw - 100%);
}

解释:你的body标签的width100vw(所以它包括滚动条的宽度)。

通过设置margin-right,只有当垂直滚动条可见时才应用页边距(因此页面内容实际上不在滚动条下面),这意味着一旦overflow-y发生更改,页面内容将不会重新定位。

注意:此解决方案仅适用于水平滚动的页面。

在Chrome 89.0, Firefox 87.0, Safari 14.0.3上测试

更新:不幸的是,它只适用于居中的容器,不采取100%宽度-否则滚动条覆盖在右侧的内容。

由于我还没有找到我的解决方案,我想补充它:

我不想要一个永久的滚动条(已接受的解决方案),我也决定不使用负边距。他们没有(立即)为我在chrome浏览器工作,我也不希望有内容可能消失在滚动条下面。

这是一个填充解决方案。

我的网页由三部分组成:

  • 标题(内容左对齐)
  • MainContent(内容居中)
  • 页脚(内容左右对齐)

因为左边填充会让标题看起来很糟糕,而且logo应该留在页面的角落,所以我保持它不变,因为滚动条的出现在大多数情况下不会影响它(除非窗口宽度非常小)。

因为均匀的填充对于MainContent和footer都是可以接受的,我只对这两个容器使用下面的css:

.main-content, .footer {
/*
* Set the padding to the maximum scrollbar width minus the actual scrollbar width.
* Maximum scrollbar width is 17px according to: https://codepen.io/sambible/post/browser-scrollbar-widths
*/
padding-right: calc(17px - (100vw - 100%));
padding-left: 17px;
}
这将保持MainContent在正中心,也适用于所有滚动条宽度不超过17px的滚动条。可以为具有覆盖滚动条的移动设备添加一个媒体查询,删除这些填充。 这个解决方案类似于只添加左边的填充,并设置宽度为“width: calc(100vw - 17px);”。我不能说它是否在所有情况下都是一样的
body {
scrollbar-gutter: stable both-edges;
}

新的css规范,将有助于滚动条重新定位的方式: https://developer.mozilla.org/en-US/docs/Web/CSS/scrollbar-gutter < / p >

总结

我认为有三种方法——每一种都有自己的特点:

这是一个StackBlitz演示

按“切换高度”键;看看内容的变化。

scrollbar-gutter

它有有限的支持,但对于@support媒体查询,我们可以使用它和overflow-y: scroll的组合:

html {
overflow-y: scroll;
}


@supports (scrollbar-gutter: stable) {
html {
overflow-y: auto;
scrollbar-gutter: stable;
}
}


这样,内容将从来没有移位。

“problem"有了这个解决方案,滚动条总是有一个固定的空间。

< >强溢出:覆盖 有限的支持,它显然隐藏了它覆盖的任何东西。需要特别注意的是,确保没有重要的东西被隐藏(也包括缩放和文本大小的变化)

可与滚动条槽结合使用:

html {
overflow-y: scroll;
}


@supports (scrollbar-gutter: stable) {
html {
overflow-y: auto;
scrollbar-gutter: stable;
}
}


@supports (overflow-y: overlay) {
html {
overflow-y: overlay;
scrollbar-gutter: auto;
}
}

可以使用一些负边距和overflow-x: hidden,但在某些情况下,这有隐藏重要内容的风险。小屏幕,自定义字体/缩放大小,浏览器扩展等。

Calc (100vw - 100%)

这可以在RTL支持下完成,如下所示:

html[dir='ltr'] main {
padding-left: calc(100vw - 100%);
}


html[dir='rtl'] main {
padding-right: calc(100vw - 100%);
}

在这种情况下,<main>将是居中内容的容器。

只要居中的容器小于<main>,这里的内容就不会移动。但一旦它是100%的容器填充将被引入。查看StackBlitz演示并点击“切换宽度”。

“problem"有了这个解决方案,你需要媒体查询,以防止填充物在“小屏幕”;即使在小屏幕上——当滚动条应该是可见的——也会发生一些移动,因为没有空间容纳100%的内容和滚动条。

< >强的结论 使用滚动条槽也许结合覆盖。如果你绝对不想要空空格,尝试介质查询的calc解决方案