手风琴折叠面板
手风琴折叠面板:点击标题展开/收起内容,常见于 FAQ 问答列表。与移动菜单的手风琴同构:max-height 过渡 + toggle .open,区别是把内容换成答案。
FAQ 常见两种模式:一次只开一个(互斥)或多个同时开。互斥模式更整齐;多开模式适合长答案对比。
- 结构:标题 button + 内容容器(max-height 0)
- max-height 设大值兜底(如 300px);内容多就调大
- 互斥模式:开新的之前先关旧的
HTML
<style> #faq { max-width: 440px; margin: 20px auto; } #faq .qa { border: 1px solid #eee; border-radius: 10px; margin-bottom: 10px; overflow: hidden; } #faq .q { width: 100%; padding: 12px 16px; text-align: left; border: none; background: #fff; cursor: pointer; font-size: 14px; } #faq .a { max-height: 0; overflow: hidden; transition: max-height .35s ease; padding: 0 16px; color: #666; font-size: 13px; } #faq .qa.open .a { max-height: 120px; padding: 0 16px 14px; } #faq .sign { float: right; color: #d2a8ff; transition: transform .3s; } #faq .qa.open .sign { transform: rotate(45deg); } </style> <div id="faq"> <div class="qa"><button class="q">什么是事件冒泡?<span class="sign">+</span></button> <div class="a">事件从最深层节点向上传递到 document 的过程,事件委托就利用了冒泡机制。</div></div> <div class="qa"><button class="q">为什么动画要用 rAF?<span class="sign">+</span></button> <div class="a">rAF 与重绘同步、后台自动暂停,比 setInterval 更平滑省电。</div></div> <div class="qa"><button class="q">max-height 过渡的坑?<span class="sign">+</span></button> <div class="a">height:auto 无法过渡,只能用足够大的 max-height 模拟,内容超出会被截断。</div></div> </div> <script> document.querySelectorAll('#faq .q').forEach(function (q) { q.addEventListener('click', function () { var qa = q.parentNode, was = qa.classList.contains('open'); document.querySelectorAll('#faq .qa').forEach(function (x) { x.classList.remove('open'); }); if (!was) qa.classList.add('open'); }); }); </script>
本节要点手风琴 = max-height 过渡 + toggle open;加号 rotate 45° 变 ✕ 是经典细节。




