在 Web 开发中,折叠面板(Accordion)是一种常见的交互组件,用于在有限的空间内展示和隐藏内容。很多时候,我们希望自己手动实现这一效果,而不是依赖第三方组件库。
本文将介绍两种实现方式:一种是利用 HTML5 的 <details>
与 <summary>
标签,另一种是利用原生 HTML、CSS 和 JavaScript 构建自定义折叠面板。
方法一:使用 <details>
和 <summary>
标签
HTML5 提供了 <details>
和 <summary>
标签,原生支持折叠和展开的交互功能,非常简单且无需 JavaScript。通过添加适当的 CSS 样式,我们还可以对其进行美化和自定义。
基本实现
1 2 3 4
| <details> <summary>面板标题</summary> <p>这是折叠面板的内容。你可以在这里放置任意 HTML 内容。</p> </details>
|
以下是实现效果:

美化 <details>
和 <summary>
的 CSS 样式
下面是一个示例,展示如何为 <details>
和 <summary>
标签设置自定义样式,包括指示图标的旋转效果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>使用 details/summary 实现折叠面板</title> <style> details { border: 1px solid #eee; border-radius: 4px; margin: 10px 0; background-color: #fff; } summary { font-size: 0.8em; font-weight: bold; cursor: pointer; list-style: none; position: relative; padding-right: 20px; padding: 8px; background-color: #fafafa; } summary::-webkit-details-marker { display: none; } summary::after { content: "\25BC"; position: absolute; right: 8px; top: 50%; transform: translateY(-50%); transition: transform 0.3s ease; } details[open] summary::after { transform: translateY(-50%) rotate(180deg); } details p { padding: 10px; margin: 0; } details img { padding: 10px; margin: 0; } </style> </head> <body> <div style="display: flex;"> <div style="flex: 1"> <details> <summary>面板标题</summary> <p> 这是第一个折叠面板的内容。使用 HTML5 的 details 标签可以轻松实现折叠效果。 </p> <img src="https://assets.kiteblog.cn/cdn-cgi/image/format=auto/blog-bg.jpg" width="300" alt="" /> </details> </div> <div style="flex: 1"> <details style="flex: 1; margin-left: 12px;"> <summary>面板标题</summary> <p> 这是第一个折叠面板的内容。使用 HTML5 的 details 标签可以轻松实现折叠效果。 </p> <img src="https://assets.kiteblog.cn/cdn-cgi/image/format=auto/blog-bg.jpg" width="300" alt="" /> </details> </div> </div> </body> </html>
|
实现效果:

说明:
- 通过
summary::-webkit-details-marker
隐藏默认的图标,然后使用 CSS ::after
伪元素添加自定义的下箭头。
- 利用
details[open]
选择器,在折叠面板展开时对图标进行旋转,实现直观的状态提示。
- 设置适当的内外边距和背景色,使面板看起来更加美观。
方法二:使用 HTML、CSS 和 JavaScript 实现自定义折叠面板
如果需要更多的自定义交互效果或兼容性要求,可以使用 HTML、CSS 和 JavaScript 手动实现折叠面板。
示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
| <!DOCTYPE html> <htmllang="zh-CN"> <head> <metacharset="UTF-8"> <metaname="viewport"content="width=device-width, initial-scale=1"> <title>自定义折叠面板</title> <style>.accordion { width: 100%; max-width: 600px; margin: 20px auto; border: 1px solid #ccc; border-radius: 4px; overflow: hidden; } .accordion-item { border-top: 1px solid #ccc; } .accordion-header { background-color: #f1f1f1; padding: 15px; font-size: 1.2em; font-weight: bold; cursor: pointer; position: relative; } .accordion-header::after { content: "\25BC"; position: absolute; right: 20px; top: 50%; transform: translateY(-50%); transition: transform 0.3s ease; } .accordion-item.active.accordion-header::after { transform: translateY(-50%) rotate(180deg); } .accordion-content { max-height: 0; overflow: hidden; transition: max-height 0.3s ease; padding: 015px; background-color: #fff; } .accordion-item.active.accordion-content { max-height: 200px; padding: 15px; } </style> </head> <body>
<divclass="accordion"> <divclass="accordion-item"> <divclass="accordion-header">面板标题 1</div> <divclass="accordion-content"> <p>这是第一个自定义折叠面板的内容。点击标题可展开或收起内容。</p> </div> </div> <divclass="accordion-item"> <divclass="accordion-header">面板标题 2</div> <divclass="accordion-content"> <p>这是第二个自定义折叠面板的内容。你可以根据需要添加任意HTML元素。</p> </div> </div> </div>
<script> header.addEventListener('click', function() { const accordionItem = this.parentElement; const isActive = accordionItem.classList.contains('active');
item.classList.remove('active'); });
accordionItem.classList.add('active'); } }); }); </script>
</body> </html>
|
说明:
- 每个
.accordion-item
包含一个标题和一个内容部分,初始时内容部分的 max-height
设置为 0,从而隐藏内容。
- 点击标题时,通过添加或移除
.active
类来控制内容展开和收起,并通过 CSS 过渡效果实现平滑动画。
- 为了让动画效果更加顺滑,实际项目中可以根据内容动态计算高度,或使用 JavaScript 计算内容高度后设置为具体值。
希望这篇博客能帮你。
Happy Coding!