使用 :has() 配合 :checked 可以完全替代 javascript 实现折叠面板。核心做法是将 <input type="checkbox"> 放在 <label></label> 内部,利用 css 选择器 .panel:has(> label > input:checked) 来检测状态,并通过 max-height 或 grid-template-rows 控制内容区域的展开与收起。

如何构建支持无限嵌套的层级结构
要实现无限层级的折叠效果,关键在于让每一层都复用相同的 HTML 结构和 CSS 逻辑。通过将 input 和 label 作为直接子元素包裹在容器内,CSS 选择器会自动向下穿透到所有后代层级,无需为不同深度编写额外的样式规则。

<div class="accordion">
<div class="panel">
<label>
<input type="checkbox">
<span>第一层标题</span>
</label>
<div class="content">
<p>第一层内容</p><p><span>立即学习</span>“<a href="https://pan.quark.cn/s/cb6835dc7db1" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">前端免费学习笔记(深入)</a>”;</p>
<div class="panel">
<label>
<input type="checkbox">
<span>第二层标题</span>
</label>
<div class="content">
<p>第二层内容</p><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/xiazai/skill12671" title="JSON Toolkit"><img
src="https://img.php.cn/upload/skill/001/246/273/6adaf20d3191a227.jpg" alt="JSON Toolkit" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/xiazai/skill12671" title="JSON Toolkit">JSON Toolkit</a>
<p>JSON文件多功能工具。支持格式化、验证、压缩、键排序及点记法路径查询。零依赖。</p>
</div>
<a href="/xiazai/skill12671" title="JSON Toolkit" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>上述代码展示了标准的嵌套结构。每个 .panel 内部包含一个 label,其中嵌入了 input。当点击 label 时,内部的 input 被选中,触发 :has() 匹配,从而改变当前 .panel 及其内部 .content 的样式。这种结构天然支持任意深度的嵌套,因为 CSS 选择器是递归应用的。
如何实现平滑过渡动画效果
由于 height: auto 无法直接参与 CSS 过渡动画,通常采用 grid-template-rows 技巧来实现平滑展开。将内容区域设为 display: grid,并将 grid-template-rows 从 0fr 过渡到 1fr。这种方法不仅性能更好,而且能完美处理内容高度未知的情况。

.panel {
border: 1px solid #ccc;
margin-bottom: 4px;
}
.panel label {
display: flex;
align-items: center;
padding: 10px;
cursor: pointer;
background: #f9f9f9;
}
.panel .content {
display: grid;
grid-template-rows: 0fr;
transition: grid-template-rows 0.3s ease-out;
}
.panel:has(> label > input:checked) .content {
grid-template-rows: 1fr;
}
.panel .content > div {
overflow: hidden;
}这段 CSS 定义了折叠面板的核心样式。.panel:has(> label > input:checked) 是关键的父级选择器,它确保只有当该面板内的标签被点击(即复选框被选中)时,才应用展开样式。grid-template-rows 的变化触发了浏览器内部的插值计算,实现了丝滑的动画效果。同时,overflow: hidden 保证了内容在过渡期间不会被裁剪溢出。
当多个面板同时展开时如何处理互斥行为
默认情况下,:has() 方案允许用户同时展开多个面板。如果需要实现手风琴效果(即展开一个面板时自动关闭其他面板),可以通过给 input 添加相同的 name 属性并配合 CSS 兄弟选择器来实现。但这会限制 :has() 的灵活性,因此更推荐保持独立展开的状态,或者通过极少量的 JS 来处理互斥逻辑。若坚持纯 CSS,可以使用 ~ 或 + 选择器针对特定相邻关系进行控制,但无法全局互斥。

















