移动端水平滚动列表添加左右渐变及滚动扩展显示效果实现
实现水平滚动列表的动态渐变侧边提示效果
你说得没错,纯CSS确实没法精准控制这种随滚动状态变化的渐变提示和padding调整,用原生Vanilla JS完全可以实现你的需求,下面我基于你提供的代码给出完整的实现方案:
核心思路
我们需要监听滚动容器的scroll事件,实时判断滚动位置:
- 当滚动距离(
scrollLeft)> 0时,说明左侧有隐藏内容,显示左侧渐变提示,并把外层容器的左padding调整为35px - 当滚动距离 < 容器最大滚动距离(
scrollWidth - clientWidth)时,说明右侧还有内容,显示右侧渐变提示 - 页面加载完成后,先判断内容是否超出容器,超出的话默认显示右侧渐变
修改后的完整代码
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>The HTML5 Herald</title> <meta name="description" content="The HTML5 Herald"> <meta name="author" content="SitePoint"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- 保证移动端适配 --> <style> .wrapper-wrapper { padding: 50px; position: relative; /* 为渐变伪元素提供定位基准 */ transition: padding-left 0.1s ease; /* 让padding变化更平滑 */ } /* 左右渐变提示的样式 */ .wrapper-wrapper::before, .wrapper-wrapper::after { content: ''; position: absolute; top: 0; bottom: 0; width: 15px; opacity: 0; transition: opacity 0.1s ease; pointer-events: none; /* 不干扰滚动操作 */ } .wrapper-wrapper.has-left-gradient::before { opacity: 1; left: 35px; /* 对应调整后的padding-left */ background: linear-gradient(to right, rgba(255,255,255,1), rgba(255,255,255,0)); } .wrapper-wrapper.has-right-gradient::after { opacity: 1; right: 50px; /* 对应原始padding-right */ background: linear-gradient(to left, rgba(255,255,255,1), rgba(255,255,255,0)); } .wrapper { -webkit-overflow-scrolling: touch; overflow-x: auto; overflow-y: hidden; white-space: nowrap; scrollbar-width: none; -ms-overflow-style: none; } .wrapper .container { max-width: none; width: -webkit-max-content; width: -moz-max-content; width: max-content; border: 7px solid green; overflow: hidden; } ::-webkit-scrollbar { display: none; } ul { clear: both; padding: 0px; list-style: none; margin: 0; font-size: 30px; } li { float: left; border: 3px solid red; padding: 30px; /* 给li加左右padding,让内容更美观 */ white-space: nowrap; } </style> </head> <body> <div class="wrapper-wrapper" id="ddd"> <div class="wrapper" id="ccc"> <div class="container" id="bbb"> <ul class="" id="aaa"> <li>This</li> <li>ul</li> <li>can</li> <li>be</li> <li>scrolled</li> <li>horizontally</li> <li>in</li> <li>the</li> <li>mobile</li> <li>mode</li> <li>hahaha</li> <li>hahaha</li> <li>hahaha</li> <li>hahaha</li> <li>hahaha</li> <li>hahaha</li> <li>hahaha</li> <li>hahaha</li> <li>hahaha</li> <li>hahaha</li> <li>hahaha</li> <li>hahaha</li> <li>hahaha</li> <li>hahaha</li> </ul> </div> </div> </div> <script> // 获取关键元素 const wrapper = document.getElementById('ccc'); const wrapperWrapper = document.getElementById('ddd'); // 定义处理滚动状态的函数 function handleScrollState() { const scrollLeft = wrapper.scrollLeft; const maxScrollLeft = wrapper.scrollWidth - wrapper.clientWidth; // 处理左侧渐变和padding if (scrollLeft > 0) { wrapperWrapper.classList.add('has-left-gradient'); wrapperWrapper.style.paddingLeft = '35px'; } else { wrapperWrapper.classList.remove('has-left-gradient'); wrapperWrapper.style.paddingLeft = '50px'; } // 处理右侧渐变 if (scrollLeft < maxScrollLeft) { wrapperWrapper.classList.add('has-right-gradient'); } else { wrapperWrapper.classList.remove('has-right-gradient'); } } // 页面加载完成后先执行一次,初始化状态 window.addEventListener('load', () => { handleScrollState(); // 监听滚动事件 wrapper.addEventListener('scroll', handleScrollState); }); </script> </body> </html>
关键代码说明
CSS部分:
- 给
.wrapper-wrapper添加position: relative,用来定位左右渐变的伪元素 - 用
::before和::after实现左右渐变,默认隐藏(opacity:0),通过添加类has-left-gradient/has-right-gradient来显示 - 给padding变化加上过渡动画,让调整更平滑
- 给
JS部分:
handleScrollState函数负责判断滚动位置,动态添加/移除渐变类,同时调整左padding- 页面加载时先执行一次函数,初始化右侧渐变(如果内容超出容器)
- 监听滚动容器的
scroll事件,实时更新状态
jQuery简化方案(如果你更习惯用jQuery)
把上面的JS部分替换成下面的代码即可:
$(document).ready(function() { const $wrapper = $('#ccc'); const $wrapperWrapper = $('#ddd'); function handleScrollState() { const scrollLeft = $wrapper.scrollLeft(); const maxScrollLeft = $wrapper[0].scrollWidth - $wrapper[0].clientWidth; if (scrollLeft > 0) { $wrapperWrapper.addClass('has-left-gradient').css('padding-left', '35px'); } else { $wrapperWrapper.removeClass('has-left-gradient').css('padding-left', '50px'); } if (scrollLeft < maxScrollLeft) { $wrapperWrapper.addClass('has-right-gradient'); } else { $wrapperWrapper.removeClass('has-right-gradient'); } } handleScrollState(); $wrapper.on('scroll', handleScrollState); });
现在你可以在Chrome移动端模式或者手机上测试这个效果,完全符合你的需求:初始时右侧显示渐变,向左滚动时左侧立即出现渐变且左padding变为35px,滚动到最右侧时右侧渐变消失,回到最左侧时左侧渐变消失、padding恢复50px。
内容的提问来源于stack exchange,提问作者Haradzieniec
相关产品推荐
相关产品推荐

