溢出:滚动;只有y轴同时保持x轴可见

时间:2017-01-08 17:40:44

标签: html css

问题案例

我正在尝试为每个列表项创建一个带有弹出窗口的滚动固定高度列表。

我使用了overflow-y: scroll;,因此可以在y轴上滚动。

然而,当我也尝试使用overflow-x: visible(为了显示溢出的弹出窗口)时,它似乎被忽略了

代码

示例1 - 列表可以滚动,但弹出窗口被剪裁

如您所见,弹出窗口(粉红色)被剪裁

.list {
  width: 72px;
  height: 132px;
  overflow-x: visible;
  overflow-y: scroll;
  background: lightgray;
}

.list li {
  position: relative;
  margin-bottom: 6px;
}

.flyout {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 64px;
  width: 128px;
  background: pink;
}
<ul class="list">
  <li>
    Item 1
    <div class="flyout">Item 1 Flyout</div>
  </li>
  <li>
    Item 2
    <div class="flyout">Item 2 Flyout</div>
  </li>
  <li>Item 3</li>
  <li>Item 4</li>
  <li>Item 5</li>
  <li>Item 6</li>
  <li>Item 7</li>
  <li>Item 8</li>
</ul>

示例2 - 列表无法滚动,弹出窗口显示正常

删除overflow-y: scroll可以很好地显示弹出窗口,但正如预期的那样,列表无法再按高度滚动。

.list {
  width: 72px;
  height: 132px;
  overflow-x: visible;
  background: lightgray;
}

.list li {
  position: relative;
  margin-bottom: 6px;
}

.flyout {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 64px;
  width: 128px;
  background: pink;
}
<ul class="list">
  <li>
    Item 1
    <div class="flyout">Item 1 Flyout</div>
  </li>
  <li>
    Item 2
    <div class="flyout">Item 2 Flyout</div>
  </li>
  <li>Item 3</li>
  <li>Item 4</li>
  <li>Item 5</li>
  <li>Item 6</li>
  <li>Item 7</li>
  <li>Item 8</li>
</ul>

可能的解决方案

我当然可以让我的.list宽度足够,所以弹出窗口不会溢出它。

我想避免这种情况,因为列表会放在绘图画布的顶部,因此它会通过鼠标阻止画布上的绘画。

使用pointer-events: none以便不阻止绘制在这种情况下不起作用,因为指针事件是必要的,以便首先检测列表的滚动事件。

3 个答案:

答案 0 :(得分:1)

因为你不能强迫孩子退出溢出的父母 - 并控制它的位置 - 这里是一个
jQuery解决方案

jQuery动态创建data-flyout元素。 在LI悬停时,它计算位置并显示弹出元素 内容取自悬停的LI var $flyout = $("<div/>", { class: "flyout", appendTo: "body", hover: function(e) { $(this).toggle(); } }); $("[data-flyout]").hover(function(e) { var par = this.parentNode; // The overlfow parent element $flyout.css({ left: this.offsetLeft + this.offsetWidth, top: this.offsetTop - par.scrollTop, }).html( this.dataset.flyout ).toggle(); });属性:

&#13;
&#13;
.list {
  width: 72px;
  height: 132px;
  overflow-x: hidden;
  overflow-y: scroll;
  background: lightgray;
}

.list li {
  position: relative;
  margin-bottom: 6px;
}

/* Created in "body" by jQuery */
.flyout {
  position: absolute;
  z-index:99999;
  display: none;
  background: pink;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<ul class="list">
  <li data-flyout="Item 1 Flyout">Item 1</li>
  <li data-flyout="Item 2 Flyout">Item 2</li>
  <li>No fly</li>
  <li data-flyout="Item 4 Flyout">Item 4</li>
  <li data-flyout="Item 5 Flyout">Item 5</li>
  <li data-flyout="Item 6 Flyout">Item 6</li>
  <li data-flyout="Item 7 Flyout">Item 7</li>
  <li data-flyout="Item 8 Flyout">Item 8</li>
</ul>
&#13;
{{1}}
&#13;
&#13;
&#13;

答案 1 :(得分:1)

您需要删除position: relative。然后,绝对定位的弹出窗口不会被overflow限制。

然而,他们不能正确滚动。您需要使用JS触发重新布局。

&#13;
&#13;
// Force relayout
var li = document.querySelector('li:last-child');
setInterval(function() {
  var parent = li.parentNode;
  var next = li.nextSibling;
  parent.removeChild(li);
  parent.insertBefore(li, next);
}, 60);
&#13;
.container {
  position: relative;
  overflow: hidden;
  margin: 1em 0;
}
.list {
  width: 72px;
  height: 132px;
  overflow-y: scroll;
  background: lightgray;
  margin: 0;
}
.list li {
  margin-bottom: 6px;
}
.flyout {
  display: inline-block;
  position: absolute;
  width: 128px;
  background: pink;
}
&#13;
<div class="container">
  <ul class="list">
    <li>
      Item 1
      <div class="flyout">Item 1 Flyout</div>
    </li>
    <li>
      Item 2
      <div class="flyout">Item 2 Flyout</div>
    </li>
    <li>Item 3</li>
    <li>Item 4</li>
    <li>Item 5</li>
    <li>Item 6</li>
    <li>Item 7</li>
    <li>Item 8</li>
  </ul>
</div>
&#13;
&#13;
&#13;

答案 2 :(得分:-2)

也许你可以利用像Superfish's vertical menu之类的东西来称呼它。

我同意上述评论,因为我没有看到纯粹的CSS方式来实现这一目标。