如何在CSS中仅在一个方向上启用滚动?

时间:2016-08-05 14:54:57

标签: html css scroll

我有一个包含一些调整大小元素的列表。调整元素大小时,它们应该沿x方向溢出容器。永远不应该在x方向滚动。应该在y方向上启用滚动。

我尝试过设置:

overflow-x: visible;
overflow-y: scroll;

但这似乎可以在两个方向上滚动。

如何防止这种情况?

https://jsfiddle.net/64tw8rqe/

CSS overflow-x: visible; and overflow-y: hidden; causing scrollbar issue的答案解释了潜在的问题,但没有解释scroll的情况。

此行为符合the spec。我正在寻找解决方法。

5 个答案:

答案 0 :(得分:2)

问题是overflow-x: visible; overflow-y: scroll是CSS中不可能的组合。只要visiblescroll配对,就会转换为auto。换句话说,这些是等价的:

overflow-x: visible;
overflow-y: scroll;

overflow-x: auto;
overflow-y: scroll;

这对规范来说是一个糟糕的决策,但有一些解决办法。

通过制作展开元素position: absolute,它们的大小不会更改容器,也不会被overflow: hidden剪裁。为了正确定位它们,在整个容器周围包含额外div position: relative <div class='container1'> <div class='container2'> <ul class='messages'> <li><pre>Hello</pre></li> <li> <pre>This is a really really really really really long message.</pre> </li> <li><pre>World</pre></li> </ul> </div> </div>

HTML:

* {
  margin: 0;
  padding: 0;
}

.container1 {
  position: relative; 
  width: 200px;
}

.container2 {
  background: #f0f;
  width: 100%;
  height: 100%;
  overflow: scroll;
}

.messages {
  overflow: visible;
  list-style: none;
}

.messages li {
  background: #ff0;
  width: 100%;
  height: 24px;
  margin-top: 12px;
}

.messages li pre {
  position: absolute;
  display: inline-block;
  box-sizing: border-box;
  width: 100%;
  max-height: 24px;
  padding: 4px;
  background: #0ff;
  border-radius: 4px;
  line-height: 16px;
  overflow: hidden;
  text-overflow: ellipsis;
  width: auto;
  min-width: 100%;
  max-width: 100%;
  transition: max-width 200ms ease-out, height 200ms ease-out;
}

.messages li pre:hover {
  z-index: 1;
  background: #00f;
  max-width: 80vw;
  max-height: 80vh;
  transition: max-width 200ms ease-in, max-height 200ms ease-in;
}

CSS:

ioctl(1, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
lstat("/run/systemd/system/", 0x7fffa5b4e300) = -1 ENOENT (No such file or directory)
execve("/lib/sysvinit/telinit", ["/usr/sbin/init"], [/* 8 vars */]) = -1 ENOENT (No such file or directory)
writev(2, [{"Couldn't find an alternative tel"..., 61}, {"\n", 1}], 2Couldn't find an alternative telinit implementation to spawn.
) = 62
exit_group(1)                           = ?
+++ exited with 1 +++

小提琴:

https://jsfiddle.net/cyL6tc2k/2/

相信这里发现的技巧:http://front-back.com/how-to-make-absolute-positioned-elements-overlap-their-overflow-hidden-parent

答案 1 :(得分:1)

当您有垂直溢出时,滚动条会添加到水平流(右侧)。元素不会覆盖滚动条,因此浏览器会将溢出设置更改为水平滚动。

您需要做的是在所有内容周围添加另一个容器,并将其设置为具有更大的宽度,内部所有溢出的内容,但内部元素和垂直滚动的高度:

<强> HTML

<div class='container3'><!-- Add a parent container -->
  <div class='container'>
    ...
  </div>
</div>

<强> CSS

/* A parent container */
.container3 {
  /* The maximum height of your inner content before scrolling is enabled */
  height: 200px;

  /* Enable the vertical scroll if we have enough content */
  overflow-y: auto;
}

<强> FIDDLE

https://jsfiddle.net/cL8hr7ot/

答案 2 :(得分:0)

这是因为你使用了“pre”,它在某些浏览器上有一些默认值:

    pre {
       display: block;
       font-family: monospace;
       white-space: pre;
       margin: 1em 0;
    }

您有两种选择:将所有“pre”更改为“p”(段落)或重写pre的空白属性,方法是添加:

    pre { white-space: normal; }

答案 3 :(得分:0)

不知道在其他地方是否有更好的答案,但是我确实提出了一个非常脆弱/棘手的解决方案。在我的示例中,它使用了一些魔术数字,但我认为这可能是将来更好地回答的起点。

此解决方案归结为使用position: absolute;,而在要成为top的项目上不使用rightbottomleftoverflow: visible的任何值{1}},并将其父级设置为overflow: scroll;

没有任何绝对值的绝对定位元素的默认行为介于我希望它位于的静态和绝对定位世界之间。

CODEPEN

Codepen

HTML

<div class="wrapper">
  <div class="inner-wrapper">
    <div class="item">Item 1</div>
    <div class="item">Item 2</div>
    <div class="item">Item 3</div>
    <div class="item">Item 4</div>
    <div class="item" id="dropdown">
      Hover me
      <div class="menu">Menu</div>
    </div>
  </div>
</div>

CSS

.wrapper {
  background: blue;
  height: 64px;
  width: 250px;
  padding: 2px;
}

.inner-wrapper {
  overflow-x: scroll;
  display: flex;
  height: 100%;
}

.item {
  background: white;
  margin-right: 2px;
  width: 60px;
  height: 100%;
  flex-shrink: 0;
}

#dropdown .menu {
  background: pink;
  height: 0px;
  position: absolute;
  display: none;
}

#dropdown:hover .menu {
  height: 100px;
  z-index: 1;
  display: block;
  margin-left: -58px;
}

我在Twitter上发布了一个我要解决的问题的小型视频片段

答案 4 :(得分:-1)

尝试更改overflow-y:hidden