防止渐变叠加滚动
Posted
技术标签:
【中文标题】防止渐变叠加滚动【英文标题】:Prevent gradient overlay from scrolling 【发布时间】:2016-06-18 12:51:01 【问题描述】:我正在尝试在滚动 div 的底部放置一个小渐变。我的解决方案基于对this SO thread 的接受答案。渐变显示得很好,但是当我滚动 div 中的内容时,渐变的底部会移动。我需要它保持原位,以便内容独立于渐变滚动。我尝试了position: fixed
、position: relative
和position: 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 将我的布局结构更改为只有一个<ul>
)。我希望我能接受两个答案。【参考方案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:防止在固定覆盖层后面滚动并保持滚动位置