You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

移动端水平滚动列表添加左右渐变及滚动扩展显示效果实现

实现水平滚动列表的动态渐变侧边提示效果

你说得没错,纯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>

关键代码说明

  1. CSS部分:

    • 给.wrapper-wrapper添加position: relative,用来定位左右渐变的伪元素
    • 用::before和::after实现左右渐变,默认隐藏(opacity:0),通过添加类has-left-gradient/has-right-gradient来显示
    • 给padding变化加上过渡动画,让调整更平滑
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 07:59:37