CSS冻结单元格(新增滚动阴影效果)

滚动带阴影效果

在这里插入图片描述


代码

<!doctype html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>table冻结单元格</title>

    <style>
        body {
            background: gray;
        }

        .box {
            width: 800px;
            height: 400px;
            overflow: auto;
        }

        table {
            border-collapse: collapse;
            width: 1000px;
            height: auto;
        }

        td {
            width: 100px;
            height: 50px;
            border: none; /* 在Chrome里,有边框会引起抖动,所以不要边框 */
            padding: 10px;
            box-sizing: border-box;
            position: relative;
            z-index: 1;
            background: #cccccc;
        }

        /* 用伪元素模拟边框 */
        td::before {
            content: "";
            width: 100%;
            height: 100%;
            position: absolute;
            z-index: 1;
            top: 0;
            left: 0;
            border-top: 1px solid #505050;
            border-left: 1px solid #505050;
            box-sizing: border-box;
        }

        tr:last-child td::before {
            border-bottom: 1px solid #505050;
        }

        td:last-child::before {
            border-right: 1px solid #505050;
        }

        /* 冻结单元格 */
        tr:nth-child(-n + 2) td, /* 前两行 */
        tr:nth-last-child(1) td, /* 后一行 */
        td:nth-child(-n + 2), /* 前两列 */
        td:nth-last-child(1) /* 后一列 */
        {
            position: sticky;
            background: #00aa00;
            z-index: 2;
        }

        /* 第一行冻结位置 */
        tr:nth-child(1) td {
            top: 0;
        }

        /* 第二行冻结位置 */
        tr:nth-child(2) td {
            top: 50px;
        }

        /* 最后一行冻结位置 */
        tr:nth-last-child(1) td {
            bottom: 0;
        }

        /* 第一列冻结位置 */
        td:nth-child(1) {
            left: 0;
        }

        /* 第二列冻结位置 */
        td:nth-child(2) {
            left: 100px;
        }

        /* 最后一列冻结位置 */
        td:nth-last-child(1) {
            right: 0;
        }

        /* 四个边角的z-index需要比其它单元格的高,不然会被覆盖 */
        tr:nth-child(-n + 2) td:nth-child(-n + 2), /* 左上角 */
        tr:nth-child(-n + 2) td:nth-last-child(1), /* 右上角 */
        tr:nth-last-child(1) td:nth-child(-n + 2), /* 左下角 */
        tr:nth-last-child(1) td:nth-last-child(1) /* 右下角 */
        {
            background: red;
            z-index: 9 !important;
        }

        /* 滚动阴影顶部 */
        .shadow-top tr:nth-child(2) td::after {
            content: "";
            position: absolute;
            left: 0;
            width: 100%;
            height: 10px;
            bottom: -10px;
            background: linear-gradient(to bottom, #505050, transparent);
        }

        /* 滚动阴影底部 */
        .shadow-bottom tr:nth-last-child(1) td::after {
            content: "";
            position: absolute;
            left: 0;
            width: 100%;
            height: 10px;
            top: -10px;
            background: linear-gradient(to top, #505050, transparent);
        }

        /* 滚动阴影左边 */
        .shadow-left td:nth-child(2)::after {
            content: "";
            position: absolute;
            top: 0;
            width: 10px;
            height: 100%;
            right: -10px;
            background: linear-gradient(to right, #505050, transparent);
        }

        /* 滚动阴影右边 */
        .shadow-right td:nth-last-child(1)::after {
            content: "";
            position: absolute;
            top: 0;
            width: 10px;
            height: 100%;
            left: -10px;
            background: linear-gradient(to left, #505050, transparent);
        }

        /* 滚动阴影垂直修正 */
        .shadow-y td:nth-child(-n + 2), /* 前两列 */
        .shadow-y td:nth-last-child(1) /* 后一列 */
        {
            z-index: 3;
        }

        /* 滚动阴影水平修正 */
        .shadow-x tr:nth-child(-n + 2) td, /* 前两行 */
        .shadow-x tr:nth-last-child(1) td /* 后一行 */
        {
            z-index: 3;
        }
    </style>
</head>
<body>
<div class="box">
    <table>
        <tr>
            <td>标题1</td>
            <td>标题2</td>
            <td>标题3</td>
            <td>标题4</td>
            <td>标题5</td>
            <td>标题6</td>
            <td>标题7</td>
            <td>标题8</td>
            <td>标题9</td>
            <td>标题10</td>
        </tr>
        <tr>
            <td>栏目1</td>
            <td>栏目2</td>
            <td>数据3</td>
            <td>数据4</td>
            <td>数据5</td>
            <td>数据6</td>
            <td>数据7</td>
            <td>数据8</td>
            <td>数据9</td>
            <td>数据10</td>
        </tr>
        <tr>
            <td>栏目1</td>
            <td>栏目2</td>
            <td>数据3</td>
            <td>数据4</td>
            <td>数据5</td>
            <td>数据6</td>
            <td>数据7</td>
            <td>数据8</td>
            <td>数据9</td>
            <td>数据10</td>
        </tr>
        <tr>
            <td>栏目1</td>
            <td>栏目2</td>
            <td>数据3</td>
            <td>数据4</td>
            <td>数据5</td>
            <td>数据6</td>
            <td>数据7</td>
            <td>数据8</td>
            <td>数据9</td>
            <td>数据10</td>
        </tr>
        <tr>
            <td>栏目1</td>
            <td>栏目2</td>
            <td>数据3</td>
            <td>数据4</td>
            <td>数据5</td>
            <td>数据6</td>
            <td>数据7</td>
            <td>数据8</td>
            <td>数据9</td>
            <td>数据10</td>
        </tr>
        <tr>
            <td>栏目1</td>
            <td>栏目2</td>
            <td>数据3</td>
            <td>数据4</td>
            <td>数据5</td>
            <td>数据6</td>
            <td>数据7</td>
            <td>数据8</td>
            <td>数据9</td>
            <td>数据10</td>
        </tr>
        <tr>
            <td>栏目1</td>
            <td>栏目2</td>
            <td>数据3</td>
            <td>数据4</td>
            <td>数据5</td>
            <td>数据6</td>
            <td>数据7</td>
            <td>数据8</td>
            <td>数据9</td>
            <td>数据10</td>
        </tr>
        <tr>
            <td>栏目1</td>
            <td>栏目2</td>
            <td>数据3</td>
            <td>数据4</td>
            <td>数据5</td>
            <td>数据6</td>
            <td>数据7</td>
            <td>数据8</td>
            <td>数据9</td>
            <td>数据10</td>
        </tr>
        <tr>
            <td>栏目1</td>
            <td>栏目2</td>
            <td>数据3</td>
            <td>数据4</td>
            <td>数据5</td>
            <td>数据6</td>
            <td>数据7</td>
            <td>数据8</td>
            <td>数据9</td>
            <td>数据10</td>
        </tr>
        <tr>
            <td>总计1</td>
            <td>总计2</td>
            <td>总计3</td>
            <td>总计4</td>
            <td>总计5</td>
            <td>总计6</td>
            <td>总计7</td>
            <td>总计8</td>
            <td>总计9</td>
            <td>总计10</td>
        </tr>
    </table>
</div>

<script>
    var box = document.querySelector('.box');

    // 记录最后滚动的距离
    var lastScrollTop = 0, lastScrollLeft = 0;

    // 监听容器滚动
    box.addEventListener('scroll', function (e) {

        // 如果当前垂直滚动距离不等于上次
        if (e.target.scrollTop !== lastScrollTop) {
            // 更新最后距离
            lastScrollTop = e.target.scrollTop;

            // 移除左右阴影样式
            box.classList.remove('shadow-left');
            box.classList.remove('shadow-right');

            // 如果滚动到顶部,移除顶部阴影样式
            if (lastScrollTop === 0) {
                box.classList.remove('shadow-top');
            }
            // 否则添加顶部阴影样式
            else {
                box.classList.add('shadow-top');
            }

            // 如果滚动到底部,移除底部阴影样式
            if (lastScrollTop + box.clientHeight === box.scrollHeight) {
                box.classList.remove('shadow-bottom');
            }
            // 否则添加底部阴影样式
            else {
                box.classList.add('shadow-bottom');
            }

            // 阴影效果修正
            box.classList.remove('shadow-x');
            box.classList.add('shadow-y');
        }

        // 如果当前水平滚动距离不等于上次
        else if (e.target.scrollLeft !== lastScrollLeft) {
            // 更新最后距离
            lastScrollLeft = e.target.scrollLeft;

            // 移除上下阴影样式
            box.classList.remove('shadow-top');
            box.classList.remove('shadow-bottom');

            // 如果滚动到左边,移除左边阴影样式
            if (lastScrollLeft === 0) {
                box.classList.remove('shadow-left');
            }
            // 否则添加左边阴影样式
            else {
                box.classList.add('shadow-left');
            }

            // 如果滚动到右边,移除右边阴影样式
            if (lastScrollLeft + box.clientWidth === box.scrollWidth) {
                box.classList.remove('shadow-right');
            }
            // 否则添加右边阴影样式
            else {
                box.classList.add('shadow-right');
            }

            // 阴影效果修正
            box.classList.remove('shadow-y');
            box.classList.add('shadow-x');
        }
    });
</script>
</body>
</html>
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值