防止渐变叠加层滚动

4

我试图在可滚动的 div 底部添加一个小渐变。我的解决方案基于这个SO线程的被接受的答案。渐变显示得很好,但是当我滚动 div 中的内容时,渐变的底部也会移动。我需要它保持在原地,以便内容可以独立于渐变滚动。我尝试过几种 position: fixedposition: relativeposition: relatve 的组合,但都无济于事。我错过了什么?

相关的标记:

<div class="resultListContainer">
    <ul class="result">
        <li><span class="resultPermitNumber resultElement">B123456789</span></li>
        <li><span class="resultPermitType resultElement">FINAL</span></li>
        <li><span class="resultDisplayAddress resultElement">41975 LOUDOUN CENTER PL SE, LEESBURG, VA 20175</span></li>
    </ul>
    <!-- Lots more of the ul. -->
</div>

相关的CSS:

.resultListContainer {
    border: 1px solid #000;
    height: 400px;
    width: 40em;
    overflow-y: scroll;
    font-size: 1em;
    position: relative;
}

.resultListContainer::before {
    background-image: linear-gradient( top, rgba( 255, 255, 255, 0 ) 0%, rgba( 255, 255, 255, 1 ) 100% );
    background-image: -moz-linear-gradient( top, rgba( 255, 255, 255, 0 ) 0%, rgba( 255, 255, 255, 1 ) 100% );
    background-image: -ms-linear-gradient( top, rgba( 255, 255, 255, 0 ) 0%, rgba( 255, 255, 255, 1 ) 100% );
    background-image: -o-linear-gradient( top, rgba( 255, 255, 255, 0 ) 0%, rgba( 255, 255, 255, 1 ) 100% );
    background-image: -webkit-linear-gradient( top, rgba( 255, 255, 255, 0 ) 95%, rgba( 255, 255, 255, 1 ) 100% );
    content: "\00a0";
    height: 100%;
    position: absolute;
    width: 100%;
}

.result {
    margin-bottom: 0;
    padding-top: 5px;
    padding-bottom: 5px;
    padding-left: 5px;
    list-style-type: none;
}

结果如下:

结果:

渐变停止滚动。

3个回答

4
因为你的元素被定位为绝对定位(absolute),它的位置相对于父元素是绝对的,所以当你滚动时,它会和你的内容一起滚动。你想要的是你的 ul 滚动。我已经快速重写了你的代码,但下面有一个简化且优化过的版本:

.resultListContainer {
    border: 1px solid #000;
    height: 400px;
    width: 40em;
    font-size: 1em;
    position: relative;
}

.resultListContainer::before {
    background-image: linear-gradient( top, rgba( 255, 255, 255, 0 ) 0%, rgba( 255, 255, 255, 1 ) 100% );
    background-image: -moz-linear-gradient( top, rgba( 255, 255, 255, 0 ) 0%, rgba( 255, 255, 255, 1 ) 100% );
    background-image: -ms-linear-gradient( top, rgba( 255, 255, 255, 0 ) 0%, rgba( 255, 255, 255, 1 ) 100% );
    background-image: -o-linear-gradient( top, rgba( 255, 255, 255, 0 ) 0%, rgba( 255, 255, 255, 1 ) 100% );
    background-image: -webkit-linear-gradient( top, rgba( 255, 255, 255, 0 ) 95%, rgba( 255, 255, 255, 1 ) 100% );
    content: "\00a0";
    height: 100%;
    position: absolute;
    width: 100%;
  z-index: 2;
  pointer-events: none;
}

.result {
  position: absolute;
  left: 0;
  top: 0;
  margin: 0;
  box-sizing: border-box;
  z-index: 1;
    width: 100%;
    height: 100%;
    margin-bottom: 0;
    padding-top: 5px;
    padding-bottom: 5px;
    padding-left: 5px;
    list-style-type: none;
    overflow-y: scroll;
}

.result li {
  height: 100px;
  background: red;
}
<div class="resultListContainer">
    <ul class="result">
        <li><span class="resultPermitNumber resultElement">B123456789</span></li>
        <li><span class="resultPermitType resultElement">FINAL</span></li>
        <li><span class="resultDisplayAddress resultElement">41975 LOUDOUN CENTER PL SE, LEESBURG, VA 20175</span></li>
        <li><span class="resultPermitNumber resultElement">B123456789</span></li>
        <li><span class="resultPermitType resultElement">FINAL</span></li>
        <li><span class="resultDisplayAddress resultElement">41975 LOUDOUN CENTER PL SE, LEESBURG, VA 20175</span></li>
        <li><span class="resultPermitNumber resultElement">B123456789</span></li>
        <li><span class="resultPermitType resultElement">FINAL</span></li>
        <li><span class="resultDisplayAddress resultElement">41975 LOUDOUN CENTER PL SE, LEESBURG, VA 20175</span></li>
    </ul>
    <!-- Lots more of the ul. -->
</div>

基本上有两件事是很重要的:您的外部框架 不能 滚动,而您的内部框架可以。所有固定元素都需要 您的内部框架之外(在此情况下为您的 ul)。其次,您的 :before 不能是 100% 高,否则它会吸收您的鼠标事件,防止滚动。除 IE 外的所有浏览器都可以通过使用 pointer-events: none 解决此问题,但最安全的方法是使您的渐变具有固定高度,并使您的 :before 元素具有您想要的渐变高度,从而产生一个(在此情况下)20px 区域,底部不会接收您的鼠标事件。

html, body { height: 100%; } body { padding: 0; margin: 0; }
div {
  width: 400px;
  height: 400px;
  max-height: 100%;
  position: relative;
}

div:before, div ul {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
}

div:before {
  background: linear-gradient(0deg, rgba(255,255,255,1), rgba(255,255,255,0));
  background-size: 100% 100%;
  height: 20px;
  z-index: 2;
  /* IE does not support pointer events, so making this small in height is important
  as your scroll events will not be passed to the ul if it is covered by your :before */
  pointer-events: none;
  content: '';
  display: block;
}

div ul {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow-y: scroll;
  z-index: 1;
}

div li {
  width: 100%;
  height: 100px;
  background: #ececec;
}

div li:nth-child(2n){
  background: #cecece;
}
<div>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
        <li>7</li>
    </ul>
</div>


1
你需要将容器包裹在一个相对定位的 div 中。
此外,覆盖层会阻止滚动条,所以我使用了 left:0; right: 16px; 替代了 width: 100%,现在滚动是可点击的。
试试我的 fiddle: https://fiddle.jshell.net/8c6k4k6d/1/

@somethinghere提供的答案非常棒且深入,并教会了我一些东西,但@Kocik直接回答了我的问题(例如,@somethinghere更改了我的布局结构,只有一个<ul>)。我希望我能接受两个答案。 - mrcoulson

0

替换

.resultListContainer::before

使用

.resultListContainer .result:last-of-type::before

这个代码将最后一个 ul.result 后的渐变色替换为一个大的白色空白区域。 - mrcoulson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接