垂直滚动条导致水平滚动条

Posted

技术标签:

【中文标题】垂直滚动条导致水平滚动条【英文标题】:Vertical Scrollbar leads to horizontal scrollbar 【发布时间】:2012-11-14 05:03:39 【问题描述】:

我的 CSS 如下所示:

div.SOMECLASS 
  position: absolute;
  max-height: 300px
  height: auto;
  width: auto;
  overflow: auto;
  ...

div 高度和宽度自动缩放。高度已经固定了一个最大值:一旦达到这个值,就会出现垂直滚动条。这一切都很好。

现在的问题: 如果出现垂直滚动条,它们会占用大约 10 像素的水平空间,因为滚动条将被放置在内部div。 但是,宽度自动缩放以允许垂直滚动条用完这些额外的 10 多像素。由于添加垂直滚动条之前的水平宽度正好适合内容(正如 width:auto 设置所预期的那样),div 现在 显示水平滚动条 - 以允许丢失10 像素。这很愚蠢。

如何避免使用这些水平滚动条,而只自动缩放 div 的宽度以使垂直滚动条适合?

如果可能的话,我正在寻找一种不依赖于完全禁用水平滚动的解决方案,因为这可能在某些时候需要(即对于某些输入)。

【问题讨论】:

尝试改用overflow-y: auto。这只会垂直放置滚动条。 【参考方案1】:

刚刚想出了一个相当可行的解决方案(至少对于我这个问题的版本而言)。

我认为width: auto 的问题在于它的行为类似于width: 100vw;问题是,当垂直滚动条出现时,viewport width 保持不变(尽管有 ~10px 滚动条),但 可视区域 (正如我所说)减少了 10 像素。

显然用 percentage 定义宽度是根据这个“可视区域”来定义的,因此将您的代码更改为:

div.SOMECLASS 
  position: absolute;
  max-height: 300px
  height: auto;
  width: 100%;
  overflow: auto;
  ...

应该允许内容正确重新缩放!

附言您也可以改为添加overflow-x: hidden,这将停止出现水平滚动条,而只需在垂直滚动条出现时从您的 div 右侧切掉约 10px。

【讨论】:

刚刚注意到这是 2 岁 - 希望它对某人有用! 将宽度:100% 添加到我所有的子 div 中删除了滚动条 :) 这不仅解决了问题,还让我更了解了问题最初是如何产生的。 我尝试了@robertking 的想法,然后逐渐删除它们以了解我真正需要应用width: 100% 的想法。谢谢大家!【参考方案2】:

我找到了一个可行但远非完美的解决方案:

我在我的 div 中添加了一个padding-right : 15px,以自动增长整个 div。现在,如果出现垂直滚动条,它们就适合填充,因此水平宽度仍然可以。

遗憾的是,当不需要垂直滚动时,当然也会显示填充,使我的 div 比它必须的宽一点...:/ 好吧,在我看来,这仍然比不需要的水平滚动条更可取.

【讨论】:

麻烦的是,15px 并不是一个跨平台的幻数。出于可访问性的原因,您的一些用户可能会有非常粗的滚动条。不幸的是,为了真正安全,您必须使用 javascript 来了解滚动条的宽度。 你是对的......这个问题真的总结了互联网的所有问题。 :// ...好吧,无论如何,使用 CSS3。除了 CSS2 中引入的系统颜色之外,也许 CSS4 将有办法访问更多系统数据。 @Michael:你知道可以用什么 Javascript(或 jQuery)技巧来找出是否有滚动条以及它的宽度,从而可以适当地扩大 div 吗? @OsakaWebbie:我不得不这样做已经有一段时间了,但对我有用的内容与这些页面上描述的内容几乎相同:chris-spittles.co.uk/jquery-calculate-scrollbar-width***.com/questions/986937/… 【参考方案3】:

通常设置100vw 是问题所在。只需将其删除,您的宽度将是 100%,无论如何这将是您想要的。

【讨论】:

【参考方案4】:

我的问题在 Google 上的搜索结果排名第一(类似于 OP,但不一样)。

这是看似不必要的水平滚动条的常见场景:

你有一个元素,比如一个表格,它使用自动调整大小。如果在添加所有行之前完成自动调整大小,则它不会为垂直滚动条计算足够的空间。在添加行之后进行调整大小解决了我的问题——即便如此,我也需要超时

this.http.get('someEndPoint').subscribe(rows => 
  this.rowData = rows;
  setTimeout(()=>sizeColumnsToFit(), 50);
);

【讨论】:

【参考方案5】:

即使没有设置固定宽度,也会出现此错误(特定于 Firefox)。

例如,如果您在灵活的包装器 div (display: inline-block;) 中有一个可垂直滚动的容器 div (overflow: auto;),那么当您将窗口大小调整为小于内容可以换行时,首先是水平滚动条将出现在您的容器 div 中,只有在那之后,灵活的包装器 div 才会增长,或者最终会在您的窗口中出现辅助水平滚动条。

结果是一个无用的水平滚动条,只能滚动垂直滚动条的宽度:

为了摆脱这个问题,您可以使用本示例中的 javascript 代码(在 Firefox 和 Chromium 中测试):

<!DOCTYPE html>
<html>
<body>
    <style type="text/css">
    .page height: 200px;width: 400px;overflow: auto;background-color: #ccc;border: 5px solid #000;margin: 5px;
    .wrapper display: inline-block;min-width: 100%;margin: 20px;
    .scroller overflow: auto;max-height: 100px;background-color: #f00;
    .content min-height: 500px;min-width: 400px;background-color: #cfc;
    </style>
    <div class="page">
        <div class="wrapper">
            <div class="scroller">
                <div class="content">
                    The wrapper-div should expand to fit the scroller content.
                    Reduce the browser window width, and a useless horizontal scrollbar appears.
                </div>
            </div>
        </div>
    </div>
    <div class="page">
        <div class="wrapper">
            <div class="scroller ensure-scrollbar-width-padding">
                <div class="content">
                    But with the javascript-function, this is now fixed.
                    There is no horizontal scrollbar in the wrapper-div.
                </div>
            </div>
        </div>
    </div>
    <script>
    var ensureScrollbarWidthPadding = function(elem)
    
        if(!parseInt(elem.scrollWidth) || !parseInt(elem.clientWidth) || !parseInt(elem.offsetWidth))
        
            return; // no browser-support for this trick
        

        var update = function()
        
            // reset to as if not having any right-padding
            elem.style.paddingRight = '0px';

            // check if horizontal scrollbar appeared only because of the vertical scrollbar
            if(elem.scrollWidth !== elem.clientWidth)
            
                elem.style.paddingRight = (elem.offsetWidth - elem.clientWidth) + 'px';
            
            else
            
                elem.style.paddingRight = '0px';
            
        ;

        window.addEventListener('resize', update, false);
        window.addEventListener('load', update, false);

        update();

        return update;
    ;

    (function()
    
        var elems = document.getElementsByClassName('ensure-scrollbar-width-padding');
        for(var i=0;i<elems.length;++i)
        
            ensureScrollbarWidthPadding(elems[i]);
        
    )();
    </script>
</body>
</html>

javascript函数ensureScrollbarWidthPadding动态添加padding-right到可垂直滚动的容器中,保证水平滚动条永远不会出现。

【讨论】:

是的。火狐的错误。在我的情况下,当我在具有white-space: nowrap; 列的表的容器 div 中有overflow: auto 时会触发它。我有多个表,其中只有 一些 具有破坏布局的水平滚动条。所以填充正确的解决方案对我不起作用

以上是关于垂直滚动条导致水平滚动条的主要内容,如果未能解决你的问题,请参考以下文章

excel表格怎么设置滚动条

如何隐藏水平滚动条并保持垂直滚动条可见,同时仍然能够水平滚动?

MFC 控件编程之水平滚动条跟垂直滚动条

如何启用垂直滚动的滚动条并禁用水平滚动?

word 中水平滚动条与垂直滚动条怎样设置与取消??

CSS 如何添加水平滚动条