防止渐变叠加滚动

Posted

技术标签:

【中文标题】防止渐变叠加滚动【英文标题】:Prevent gradient overlay from scrolling 【发布时间】:2016-06-18 12:51:01 【问题描述】:

我正在尝试在滚动 div 的底部放置一个小渐变。我的解决方案基于对this SO thread 的接受答案。渐变显示得很好,但是当我滚动 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;

结果:

【问题讨论】:

【参考方案1】:

您需要将容器包装在另一个定位为相对的 div 中。

此外,覆盖会阻止您的滚动条,所以我使用 width: 100% 代替:left:0; right: 16px; - 现在滚动是可点击的。

试试我的小提琴: https://fiddle.jshell.net/8c6k4k6d/1/

【讨论】:

@somethinghere 提供的答案很棒而且很深入,教会了我一些东西,但@Kocik 直接回答了我的问题(例如,@somethinghere 将我的布局结构更改为只有一个&lt;ul&gt;)。我希望我能接受两个答案。【参考方案2】:

因为您的元素位于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>

【讨论】:

【参考方案3】:

替换

.resultListContainer::before

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

【讨论】:

这个在最后一个ul.result之后将渐变换成一个大的白色空白区域。

以上是关于防止渐变叠加滚动的主要内容,如果未能解决你的问题,请参考以下文章

如何防止表格视图滚动到视图后面?

iOS 10 Safari:防止在固定覆盖层后面滚动并保持滚动位置

如何防止 CSS 渐变色带?

防止定时器叠加

UIPopoverController 按钮,防止变暗叠加?

动态加载echarts数据,防止动态加载后数据叠加