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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13569610/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 20:52:36  来源:igfitidea点击:

Vertical Scrollbar leads to horizontal scrollbar

cssscrollbarhorizontal-scrollingvertical-scrolling

提问by fgysin reinstate Monica

My CSS looks like this:

我的 CSS 看起来像这样:

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

The div height and width scale automatically. The height has fixed a maximum though: as soon as this value is reached vertical scrollbars appear. This works all pretty swell.

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

Now the issue:
If the vertical scrollbars appear, they use up around 10px of horizontal space, as the scrollbars will be placed insidethe div.
However, the width is notautoscaled to allow for these additional 10-something pixels used up by the vertical scrollbars. As the horizontal width before the adding the vertical scrollbars was just exactly right for the content (as expected from the width:autosetting), the divnow alsodisplays horizontal scrollbars - to allow for the missing 10 pixels. This is silly.

现在的问题:
如果垂直滚动条出现,他们使用了周围的10px的水平空间,如滚动条将放在里面div
但是,宽度不会自动缩放以允许垂直滚动条使用这些额外的 10 像素左右。由于添加垂直滚动条之前的水平宽度正好适合内容(正如width:auto设置所预期的那样),div现在显示水平滚动条 - 以允许丢失的 10 个像素。这是愚蠢的。

  • How can I avoid having these horizontal scrollbars and just autoscale the width of the divto make the vertical scrollbars fit?
  • 如何避免使用这些水平滚动条而仅自动缩放 的宽度div以使垂直滚动条适合?

If possible I am looking for a solution which does not rely on just completely disabling horizontal scrolling, as this will probably be needed at some point (i.e. for certain inputs).

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

采纳答案by fgysin reinstate Monica

I found a solution which is working but far from perfect:

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

I added a padding-right : 15pxto my div, to automatically grow the entire div. Now if the vertical scrollbars appear, they fit within the padding so the horizontal width is still ok.

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

Regretfully the padding of course also shows up when no vertical scrolling is needed, making my div just a tiny bit wider than it would have to be... :/ Well, in my eyes this is still preferable to unneeded horizontal scrollbars.

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

回答by Spencer

Just figured out a pretty passable solution (at least for my version of this problem).

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

I assume the issue with width: autois that it behaves similarly to width: 100vw; the problem is that when the vertical scrollbar appears, the viewport widthremains the same (despite the ~10px scrollbar), but the viewable area(as I'm calling it) is reduced by 10px.

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

Apparently defining width by percentagedefines it in terms of this "viewable area", so changing your code to:

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

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

should allow the content to rescale properly!

应该允许内容正确缩放!

p.s. You can also instead add overflow-x: hidden, which will stop the horizontal scrollbar from appearing, instead simply cutting ~10px off of the right side of your div when the vertical scrollbar appears.

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

回答by solbs

Number 1 search result on Google for my problem (similar to OP, but not the same).

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

Here is a common scenario for seemingly unnecessary-horizontal-scrollbar:

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

You have an element, say, a table, which uses auto-sizing. If the auto-sizing is done beforeall the rows are added, then it will not calculate enough room for a vertical-scrollbar. Doing the resize afteradding rows fixed my issue -- even then, I needed a timeout

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

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

回答by bersling

Often setting 100vwis the problem. Just remove it and your width will be 100%, which will be what you want anyways.

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

回答by Yeti

This bug (specific to Firefox) occurs even when not setting a fixed width.

即使未设置固定宽度,也会发生此错误(特定于 Firefox)。

For instance, if you have a vertically scrollable container div (overflow: auto;) inside a flexible wrapper div (display: inline-block;), then when you resize the window to be smaller than the content can wrap, first, a horizontal scrollbar will appear in your container div, and only after that, the flexible wrapper div will grow or eventually a secondary horizontal scrollbar will appear in your window.

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

The result is a useless horizontal scrollbar, that only can scroll the width of the vertical scrollbar:

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

Screenshot of the example code showing the problem and a solution

Screenshot of the example code showing the problem and a solution

In order to get rid of this issue, you could use the javascript-code from this example (tested in Firefox and Chromium):

为了摆脱这个问题,您可以使用本示例中的 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>

The javascript function ensureScrollbarWidthPadding dynamically adds a padding-rightto the vertically scrollable container, to ensure that the horizontal scrollbar will never appear.

javascript 函数ensureScrollbarWidthPadding 动态地padding-right给垂直可滚动的容器添加a ,以确保水平滚动条永远不会出现。