原生 HTML 的 details/summary 可实现折叠展开与文字切换:纯 CSS 方案用 ::before 伪元素切换“展开/收起”提示,兼容性好但无法动态更新内容;需响应式文本(如条目数)则必须用 JS 监听 toggle 事件修改 summary.textContent 并同步 aria-expanded 属性。

用 details 和 summary 最简实现折叠展开与文字切换
原生 HTML 就能搞定,不需要 JS 或 CSS 框架。关键是利用 details 的开闭状态驱动 summary 内部文本动态变化——但注意:details 本身不提供状态钩子,得靠 CSS 伪元素或 JS 监听。
-
details默认可折叠,open属性表示展开态,初始不加即收起 -
summary必须是details的第一个子元素,点击它触发切换 - 纯 CSS 方案只能靠
::before或::after切换提示文字(如“展开”/“收起”),不能真正替换summary文本节点 - 如果需要精确控制文字内容(比如显示剩余条目数),必须用 JS 监听
toggle事件
纯 CSS 实现“展开/收起”文字提示切换(无 JS)
利用 details[open] summary::before 选择器,在展开时覆盖默认文字。前提是把原始文字用 span 包裹并设为 display: none,再用伪元素生成可见文案。
<details><summary><span style="display:none">展开</span>
</summary>
折叠区内容……
</details><style>
details summary::before {
content: "展开";
}
details[open] summary::before {
content: "收起";
}
details summary span {
display: none;
}
</style>
- 伪元素方案兼容性好(Chrome 12+、Firefox 49+、Safari 6.2+),但无法响应式更新动态数据(如“展开(3 条)”)
- 不要在
summary里直接写文字再用visibility: hidden遮盖——部分浏览器仍会读屏朗读,影响无障碍 - 若需图标(▶/▼),直接加在
::before的content里,用 Unicode 或 base64 data URL
JS 监听 toggle 事件实时更新 summary 文本
当提示文字需反映真实状态(如“显示全部 12 条” → “仅显示前 5 条”),必须用 JS 修改 summary.textContent。监听 toggle 事件比轮询 open 属性更可靠。
<details id="itemList"><summary>展开(共 12 条)</summary><div>...列表项...</div>
</details><script>
const details = document.getElementById('itemList');
details.addEventListener('toggle', () => {
const summary = details.querySelector('summary');
if (details.open) {
summary.textContent = '收起(共 12 条)';
} else {
summary.textContent = '展开(共 12 条)';
}
});
</script>
-
toggle事件在用户点击或脚本调用details.open = true/false时都触发,比监听click更健壮 - 避免在事件回调里反复调用
textContent = ...而不判断当前状态,否则可能造成文字抖动 - 若页面有多个
details,建议用事件委托绑定到父容器,再用event.target.matches('details')过滤
移动端点击区域小、动画生硬?补点 CSS 优化
summary 默认点击热区窄,且原生切换无过渡动画。这两处不处理,用户会觉得“卡”或“点不中”。
- 给
summary加padding扩大热区,例如padding: 8px 12px;禁用默认 outline 后补上 focus 样式,保无障碍 - 折叠内容区域用
details[open] > *:not(summary)控制高度 +transition: max-height做渐显(注意:max-height 需设具体值,不能用none) - 不要对
details本身设height或overflow,会破坏原生行为;动画只作用于其后续兄弟元素 - Safari 对
details的toggle事件支持稳定,但旧版 iOS 可能需加-webkit-appearance: none重置样式
细节容易被忽略:伪元素方案在屏幕阅读器中可能朗读两次(原始隐藏文本 + 伪元素内容),而 JS 方案若未同步更新 aria-expanded,会影响读屏体验。真要兼顾功能、性能和可访问性,优先用 JS 方案,并手动维护 aria-expanded 属性。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











