纯 CSS 实现带连接线的树形组件(div版)

看到XboxYan写的《纯 CSS 实现带连接线的树形组件》,随手改了个div版本,这下没有details和summary的也能用了。

css:

css 复制代码
<style>
    .treeview div.summary{
            outline: 0;
            padding-left: 30px;
            background: repeating-linear-gradient( 90deg, #999 0 1px,transparent 0px 2px) 0px 50%/20px 1px no-repeat;
    }
    .treeview div.details>div.details:last-child{
            background-size: 1px 23px;
    }
    .treeview>div.details:not(:last-child)>div.details:last-child{
            background-size: 1px 100%;
    }
    .treeview div.details{
            padding-left: 38px;
            background: repeating-linear-gradient( #999 0 1px,transparent 0px 2px) 38px 0px/1px 100% no-repeat;
    }
    .treeview div.details>div.details{
            display: none;
            transition: .2s;
    }
    .treeview div.open>div.details{
            display: block;
            transition: .2s;
    }
    .treeview>div.details{
            background: none;
            padding-left: 0;
    }
    .treeview>div.details>div.summary{
            background: none;
            padding-left: 0;
    }
    .treeview>div.details>div.details{
            padding-left: 8px;
            background: repeating-linear-gradient( #999 0 1px,transparent 0px 2px) 8px 0px/1px 100% no-repeat;
    }
    .treeview div.summary{
            display: flex;
            align-items: center;
            height: 46px;
            font-size: 15px;
            line-height: 22px;
            color: rgba(0, 0, 0, 0.85);
            cursor: default;
    }
    .treeview div.summary::after{
            content: '';
            position: absolute;
            left: 10px;
            right: 10px;
            height: 38px;
            background: #EEF2FF;
            border-radius: 8px;
            z-index: -1;
            opacity: 0;
            transition: .2s;
    }
    .treeview div.summary:hover::after{
            opacity: 1;
    }
    .treeview div.summary:not(:only-child)::before{
            content: '';
            width: 14px;
            height: 14px;
            flex-shrink: 0;
            margin-right: 8px;
            border: 1px solid #999;
            background: linear-gradient(#999, #999) 50%/1px 10px no-repeat,linear-gradient(#999, #999)  50%/10px 1px no-repeat;
    }
    .treeview div.open>div.summary::before{
            background: linear-gradient(#999, #999) 50%/10px 1px no-repeat;
    }
</style>

html:

html 复制代码
<div class="treeview" id="treeview">
        <div class="details">
                <div class="summary tree-item">项目1</div>
                <div class="details">
                        <div class="summary tree-item">文件夹</div>
                        <div class="details">
                                <div class="summary tree-item">sdd</div>
                        </div>
                </div>
                <div class="details">
                        <div class="summary tree-item">chrome test</div>
                </div>
        </div>

        <div class="details">
                <div class="summary tree-item">项目2</div>
                <div class="details">
                        <div class="summary tree-item">文件夹2-1</div>
                        <div class="details">
                                <div class="summary tree-item">文件夹2-1-1</div>
                                <div class="details">
                                        <div class="summary tree-item">文件夹2-1-1-1</div>
                                        <div class="details">
                                                <div class="summary tree-item">文件夹2-1-1-1-1</div>
                                                <div class="details">
                                                        <div class="summary tree-item">文件夹2-1-1-1-1-1</div>
                                                </div>
                                        </div>
                                </div>
                        </div>
                </div>
        </div>

        <div class="details">
                <div class="summary tree-item">文件夹1</div>
                <div class="details">
                        <div class="summary tree-item">文件夹</div>
                </div>
                <div class="details">
                        <div class="summary tree-item">文件夹2</div>
                </div>
        </div>

        <div class="details">
                <div class="summary tree-item">项目3</div>
                <div class="details">
                        <div class="summary tree-item">文件夹1</div>
                        <div class="details">
                                <div class="summary tree-item">1</div>
                                <div class="details">
                                        <div class="summary tree-item">文件夹2</div>
                                </div>
                        </div>
                </div>
                <div class="details">
                        <div class="summary tree-item">文件夹</div>
                </div>
                <div class="details">
                        <div class="summary tree-item">文件夹</div>
                </div>
                <div class="details">
                        <div class="summary tree-item">文件夹</div>
                </div>
                <div class="details">
                        <div class="summary tree-item">文件夹的副本</div>
                </div>
                <div class="details">
                        <div class="summary tree-item">点点点</div>
                </div>
                <div class="details">
                        <div class="summary tree-item">hewei</div>
                        <div class="details">
                                <div class="summary tree-item">hewei02</div>
                        </div>
                </div>
        </div>
</div>

script:(如需兼容更低版本,可以用jQuery实现)

js 复制代码
<script>
        document.addEventListener('DOMContentLoaded', function() {
                let summaries = document.querySelectorAll('#treeview div.summary');
                summaries.forEach(summary => {
                        summary.addEventListener('click', (e)=>{
                                if (e.currentTarget.nextElementSibling !== null)
                                        e.currentTarget.parentElement.classList.toggle('open');
                        });
                });
        });
</script>
相关推荐
Mike_jia4 分钟前
SSM平台:Ansible与Docker融合的运维革命——轻量级服务器智能管理指南
前端
yinuo5 分钟前
Uni-App跨端开发实战:编译微信小程序跳转全平台终极指南(01)
前端
小流苏生8 分钟前
或许,找对象真的太难了……
前端·后端·程序员
前端小巷子17 分钟前
Vue 3 模板编译器
前端·vue.js·面试
江城开朗的豌豆18 分钟前
为什么在render里调setState,代码会和你“翻脸”?
前端·javascript·react.js
江城开朗的豌豆20 分钟前
子组件改状态,父组件会“炸毛”吗?
前端·javascript·react.js
晓得迷路了21 分钟前
栗子前端技术周刊第 96 期 - Rspack v1.5、ESLint v9.34.0、Bun v1.2.1...
前端·javascript·bun
Sapphire~21 分钟前
重学JS-004 --- JavaScript算法与数据结构(四)JavaScript 表单验证
前端·javascript·数据结构·算法
程序视点29 分钟前
局域网文件传输神器LocalSend:比微信QQ更快更安全的跨平台传输方案
前端·后端
用户61204149221333 分钟前
springboot+vue+小程序做的积分兑换系统
前端·vue.js·spring boot