CSS溢出-x:可见;和溢出-y:隐藏;导致滚动条问题

Posted

技术标签:

【中文标题】CSS溢出-x:可见;和溢出-y:隐藏;导致滚动条问题【英文标题】:CSS overflow-x: visible; and overflow-y: hidden; causing scrollbar issue 【发布时间】:2011-09-19 07:13:54 【问题描述】:

假设你有一些样式和标记:

ul

  white-space: nowrap;
  overflow-x: visible;
  overflow-y: hidden;
/* added width so it would work in the snippet */
  width: 100px; 

li

  display: inline-block;
<div>
  <ul>
    <li>1</li> <li>2</li> <li>3</li>
    <li>4</li> <li>5</li> <li>6</li>
    <li>7</li> <li>8</li> <li>9</li>
    <li>1</li> <li>2</li> <li>3</li>
    <li>4</li> <li>5</li> <li>6</li>
    <li>7</li> <li>8</li> <li>9</li>
    <li>1</li> <li>2</li> <li>3</li>
    <li>4</li> <li>5</li> <li>6</li>
    <li>7</li> <li>8</li> <li>9</li>
  </ul>
</div>

当您查看此内容时。 &lt;ul&gt; 在底部有一个滚动条,尽管我已经为溢出 x/y 指定了可见和隐藏值。

(在 Chrome 11 和 Opera (?) 上观察到)

我猜肯定有一些 w3c 规范或某些东西告诉这种情况发生,但对于我的生活,我无法弄清楚为什么。

JSFiddle

更新:-我找到了一种方法来获得相同的结果,方法是在ul 周围添加另一个元素。 Check it out.

【问题讨论】:

你想要的结果是什么? jsfiddle.net/Kyle_Sevenoaks/3xv6A/2 @kyle 它应该看起来更像:jsfiddle.net/3xv6A/5 不幸的是,如果我设置 overflow-x hidden; 它会删除滚动,但因为我需要 li 元素来隐藏底部的边框,所以它给出了所需的虚线效果。我不明白为什么overflow-x: visible 创建滚动条。它不应该afaik。 @JamesKhoury 你能详细说明一下你的解决方案吗?我真的不能让它工作 @GeorgeKatsanos 解决方法:jsfiddle.net/3xv6A/9 依赖于父级为 overflow: hidden; 和插入在&lt;ul&gt; 周围的子级为overflow: visible @JamesKhoury 你认为它适用于embed.plnkr.co/2rbaISwvzuKhyPEFpBKD 【参考方案1】:

经过一番认真的搜索,我似乎找到了问题的答案:

来自:http://www.brunildo.org/test/Overflowxy2.html

在 Gecko、Safari、Opera 中,“可见” 与 “隐藏”(换句话说:“可见” 结合使用时变为“自动” 其他任何不同的东西 '可见的')。 Gecko 1.8、Safari 3、Opera 9.5 之间非常一致。

W3C spec 也说:

‘overflow-x’的计算值 和'overflow-y'和他们的一样 指定的值,除了一些 与“可见”的组合不是 可能的:如果一个被指定为 “可见”,另一个是“滚动”或 “自动”,然后“可见”设置为 '汽车'。的计算值 “溢出”等于计算的 如果“溢出-y”,则“溢出-x”的值 是一样的;否则就是一对 'overflow-x' 的计算值和 ‘溢出-y’。

短版:

如果您将visible 用于overflow-xoverflow-y,而将visible 以外的其他值用于另一个,则visible 值将被解释为auto

【讨论】:

我知道 W3C 是这样规定的,但背后的动机是什么?我发现它非常奇怪和不一致的行为,导致需要添加琐碎的 HTML 元素的混乱解决方法。 @Erwin 我同意,希望有人决定更新规范。 你是对的,但它没有任何意义。您甚至想要 x 和 y 的最常见原因是,您可以将一个隐藏而另一个可见。 这太严重了。为什么我们不能在 overflow-y:hidden 期间允许 overflow-x:visible 没有父/子黑客攻击?漂亮的铺位,IMO。 这完全是致命的。我试图在 Bootstrap 导航栏中水平滚动一堆下拉链接,但这会破坏依赖overflow-y: visible 的下拉列表。嘘 CSS!【参考方案2】:

另一个廉价的黑客,似乎可以解决问题:

style="padding-bottom: 250px; margin-bottom: -250px;" 位于垂直溢出被截断的元素上,250 代表下拉列表所需的尽可能多的像素,等等。

【讨论】:

这使得水平滚动条看起来那么远 这也会阻止元素下方 250px 的指针事件。但我找到了解决方法,我正在使用这个解决方案。 在我的特定场景中,无法删除 position: relative 或使用包装器,这是唯一有效的解决方案,尽管它还需要为元素内的子元素添加很多丑陋的边距我想设置overflow-x: hidden 以补偿hacky 填充。不过,这救了我,所以谢谢! 我在水平方向上尝试了这个,结果垂直滚动的 div 也可以水平滚动。 2020,这对我有帮助……尽管对我来说那样做是行不通的。我必须添加填充,然后为前面的元素添加负边距,以缩小差距。不过,这让我朝着正确的方向前进,谢谢!【参考方案3】:

我最初在使用 Cycle jQuery 插件时发现了一种 CSS 方法来绕过这个问题。 Cycle 使用 javascript 将我的幻灯片设置为overflow: hidden,因此当我将图片设置为width: 100% 时,图片看起来会垂直切割,所以我强制它们使用!important 可见,并避免在幻灯片中显示幻灯片动画我将overflow: hidden 设置为幻灯片的容器 div。希望它对你有用。

更新 - 新解决方案:

原来的问题 -> http://jsfiddle.net/xMddf/1/ (即使我使用overflow-y: visible,它也会变成“自动”,实际上是“滚动”。)

#content 
    height: 100px;
    width: 200px;
    overflow-x: hidden;
    overflow-y: visible;

新的解决方案 -> http://jsfiddle.net/xMddf/2/ (我发现了一种解决方法,使用 wrapper div 将 overflow-xoverflow-y 应用于不同的 DOM 元素,因为 James Khoury 建议将 visiblehidden 组合到单个 DOM 的问题元素。)

#wrapper 
    height: 100px;
    overflow-y: visible;

#content 
    width: 200px;
    overflow-x: hidden;

【讨论】:

这是如何应用的?它似乎不适用于overflow-x 或overflow-y。 @Macumbaomuetre 这更清楚,谢谢+1。它类似于我添加的“更新”。最初我无法更改包装 div,我的解决方案最终类似于:jsfiddle.net/3xv6A/338 此解决方案不适用。问题是overflow-x:visible;overflow-y:hidden。不是相反。 @TomasJansson @Edward 它确实工作,你只需要交换你应用overflow-x-y的位置:updated fiddle。 一旦包装器由于某种原因获得宽度,这就会失败 - jsfiddle.net/ad1941k9/16【参考方案4】:

我在尝试构建具有垂直可滚动内容和嵌套绝对定位子项固定定位侧边栏时遇到了这个问题显示在侧边栏边界之外

我的方法包括单独申请:

侧边栏元素的overflow: visible 属性 侧边栏内部包装的 overflow-y: auto 属性

请查看以下示例或online codepen。

html 
  min-height: 100%;

body 
  min-height: 100%;
  background: linear-gradient(to bottom, white, DarkGray 80%);
  margin: 0;
  padding: 0;


.sidebar 
  position: fixed;
  top: 0;
  right: 0;
  height: 100%;
  width: 200px;
  overflow: visible;  /* Just apply overflow-x */
  background-color: DarkOrange;


.sidebarWrapper 
  padding: 10px;
  overflow-y: auto;   /* Just apply overflow-y */
  height: 100%;
  width: 100%;


.element 
  position: absolute;
  top: 0;
  right: 100%;
  background-color: CornflowerBlue;
  padding: 10px;
  width: 200px;
<p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?</p>
<div class="sidebar">
  <div class="sidebarWrapper">
    <div class="element">
      I'm a sidebar child element but I'm able to horizontally overflow its boundaries.
    </div>
    <p>This is a 200px width container with optional vertical scroll.</p>
    <p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?</p>
  </div>
</div>

【讨论】:

我很确定这与其他人提出的解决方案相同,但使用 auto 而不是 hidden【参考方案5】:

现在有一种解决此问题的新方法 - 如果您从需要使溢出-y 可见的容器中删除position: relative,则可以使溢出-y 可见和溢出- x 隐藏,反之亦然(overflow-x 可见,overflow-y 隐藏,只要确保具有 visible 属性的容器没有相对定位即可)。

有关更多详细信息,请参阅 CSS Tricks 的这篇文章 - 它对我有用:https://css-tricks.com/popping-hidden-overflow/

【讨论】:

但是如果它是绝对的,则需要一些 javascript 来正确定位元素【参考方案6】:

我使用了内容 + 包装器的方法...但是我做了一些与目前为止提到的不同的事情:我确保我的包装器的边界与内容的边界在我希望可见的方向

重要提示:根据positionoverflow-* 等的各种 CSS 组合,在一个或另一个浏览器上使用内容 + 包装器、相同边界的方法很容易,但我永远不会使用使它们全部正确的方法(Edge、Chrome、Safari 等)。

但是当我有类似的东西时:

#hack_wrapper 
    position:absolute; 
    width:100%; 
    height:100%; 
    overflow-x:hidden;


#content_wrapper 
    position:absolute; 
    width:100%; 
    height:15%; 
    overflow:visible;
<!-- #hack_wrapper div created solely for this purpose --> 
<div id="hack_wrapper">
    <div id="content_wrapper">         
          ... this is an example of some content with far too much horizontal content... like, way, way, way too much content.
    </div>
</div>

...所有浏览器都很满意。

【讨论】:

【参考方案7】:

对于我的用例,将overflow-x:visible; overflow-y:clip 添加到有溢出的 div 上似乎给了我在 Y 轴上隐藏溢出而不在 X 轴上给我滚动条的预期效果(我有一个轮播滑块在再次缩小之前加载全尺寸图片,这些图片在加载时占据了页面高度的 75%,因此不需要overflow-y)。

不需要父包装 div,只需在溢出元素上设置一个固定的height。我意识到这个解决方案可能并不适合所有人,但它肯定可以帮助一些人。

【讨论】:

【参考方案8】:

如果您只希望第一行可见(但仍需要溢出),那么一个小“hack”效果很好:

将间隙设置得非常高,以便您确定第二行被推出屏幕 - 例如:

gap: 10000rem;

它真的很hacky,但非常适合带有需要溢出菜单的桌面导航之类的东西......

【讨论】:

gap 属性仅适用于(并且仅设计用于)弹性盒和网格布局。如果您不使用display: griddisplay: flex,它不会做任何事情。

以上是关于CSS溢出-x:可见;和溢出-y:隐藏;导致滚动条问题的主要内容,如果未能解决你的问题,请参考以下文章

溢出-x:隐藏;不会工作,但溢出-x:滚动;将要?

日期选择器部分被溢出-y滚动隐藏

使用溢出时无法隐藏滚动条:自动

如何用css控制浏览器滚动条

如何用css控制浏览器滚动条

想x轴超出隐藏,y轴超出内容显示.overflow-x:hidden; overflow-y:visible;这样写,y轴会出滚动条怎么办呢