防止{overflow-y:auto} div中的绝对定位元素触发滚动条

时间:2015-03-24 22:55:14

标签: html css

设置overflow-y时,是否有办法防止绝对定位的元素触发滚动条?我认为它不会,因为绝对定位的元素通常不会影响父元素的宽度/高度。出于某种原因,在设置overflow-y:auto时确定是否显示滚动条似乎并不重要。有没有办法解决这个问题,而不将下拉内容放在DOM中完全不同的位置?

我只希望通常会使元素增长的东西能够触发滚动条。

overflow-y problem demonstration

这是一个显示问题的代码:

http://codepen.io/isaksky/pen/zxedXe

2 个答案:

答案 0 :(得分:3)

由于性能问题,IMO用户代理使用overflow 以外的visible覆盖绝对定位的元素

因为在滚动过程中他们必须重新绘制(并改变位置)与containing block相关的绝对定位元素。

同样的事情发生在漂浮物的存在 - 见:


一种可能的选择可能是让绝对定位的元素相对于initial containing block<html>元素所在的位置)而言。

为了实现这一点,我们可以从position: relative中删除#dialog-1,因此绝对定位元素的包含块将是初始包含块。它也随页面一起滚动。

<强> Example Here

&#13;
&#13;
function forAllNodes(nodes, fn) {
  Array.prototype.forEach.call(
    nodes,
    function(node) {
      fn.call(node);
    }
  );
}

var layoutGate = function() {
  forAllNodes(
    document.querySelectorAll('.dropdown-contents'),
    function() {
      if (this.classList) this.classList.toggle('hide');
    }
  );
};

var intervalId = setInterval(layoutGate, 1000);

forAllNodes(
  document.querySelectorAll('.toggle-dropdown-btn'),
  function() {
    var elm = this;
    elm.addEventListener('click', function() {
      if (intervalId) {
    	clearInterval(intervalId);
   		intervalId = null;    
      }
      layoutGate();
    }, false);
  }
);
&#13;
.wrapper {
  padding-left: 20px;
}

p {
  line-height: 1.3em;
}

#dialog-1 {
  padding: 10px;
  border: 3px solid black;
  width: 400px;
  min-height: 100px;
  max-height: 150px;
  overflow-y: auto;
}

.dropdown-control {
  /* position: relative; */
  margin: 0;
  padding: 0;
}

.toggle-dropdown-btn {
  padding: 0;
  margin: 0;
}

.dropdown-contents {
  list-style-type: none;
  position: absolute;
  /* min-width: 100%; */
  width: 400px;
  background-color: #81d4fa;
  margin: 0;
  padding: 0;
  border: 1px solid green;
  /* top: 100%; */
  /* left: 0; */
}

#dialog-2 {
 padding: 10px;
  border: 3px solid black;
  width: 400px;
  min-height: 100px;
  max-height: 150px;
}

.hide {
  display: none;
}
&#13;
<div class="wrapper">
  <h1>Div with overflow-y:</h1>
  <div id="dialog-1">
    <p>Stuff in Dialog blah blah</p>

    <div class="dropdown-control">
      <button type="button" class="toggle-dropdown-btn">Toggle Dropdown</button>
      <ul class="dropdown-contents">
        <li>why</li>
        <li>do i </li>
        <li>trigger </li>
        <li>scroll</li>
      </ul>  
    </div>
  </div>

  <h1>Normal div, no overflow-y</h1>
  <div id="dialog-2">
    <p>Stuff in Dialog blah blah</p>
    <div class="dropdown-control">
      <button type="button" class="toggle-dropdown-btn">Toggle Dropdown</button>
      <ul class="dropdown-contents">
        <li>this</li>
        <li>does not </li>
        <li>grow </li>
        <li>the div</li>
      </ul>  
    </div>
  </div>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

非常简单的答案 - 不,没有 解决方法 ,因为您没有修复错误或不准确的实施。如果你想使用HTML / CSS,那么你必须遵守它的规则。你可以做的是让你绝对定位的div成为你overflow-y: auto div的兄弟,但是,正如你所见,它不能成为它的孩子。

&#13;
&#13;
.container { position: relative; }
.scroll-container { overflow-y: auto; border: 3px solid #000; height: 90px; }
.abs { position: absolute; top: 100%; margin-top: -10px; left:0; right:0; background:#0f0; padding: 50px;}
&#13;
<div class="container">
  
  <div class="scroll-container">
    this <br>
    is <br>
    an <br>
    overflow <br>
    div <br>
    that <br>
    scrolls <br>
  </div><!-- .scroll-container -->
  
  <div class="abs">
    an absolutely positioned div
  </div><!-- .abs -->
  
</div><!-- .container -->
&#13;
&#13;
&#13;