details标签原生支持手风琴折叠,无需JS即可实现展开/收起,但默认为多选独立模式;要实现单选互斥需JS,CSS仅能模拟;summary必须为details第一个子元素,图标旋转用[open]伪类控制,且需注意无障碍与兼容性。

details标签默认行为就是手风琴折叠的核心
原生 <details> 标签自带展开/收起状态管理,不需要任何 JS 就能响应点击。它的子元素 <summary> 是唯一可点击触发切换的区域,浏览器自动处理状态切换和 ARIA 属性(如 aria-expanded),且支持键盘操作(空格/回车)。
关键点:<summary> 必须是 <details> 的**第一个子元素**,否则无法触发折叠逻辑;后续所有内容都会被折叠/展开。
多个details并列时默认各自独立,不自动互斥
如果你希望“点一个,其他收起”(典型手风琴效果),<details> 本身不提供这个行为——它天生是独立开关。要纯 HTML 实现互斥,目前**没有标准方案**,必须借助 CSS 或 JS。
但有一个实用妥协:用 CSS 的 :has() 配合相邻兄弟选择器,在支持的浏览器中模拟单开效果(注意兼容性):
立即学习“前端免费学习笔记(深入)”;
<details class="accordion-item"> <summary>标题1</summary> <p>内容1</p> </details> <details class="accordion-item"> <summary>标题2</summary> <p>内容2</p> </details>
然后加这段 CSS(仅 Chromium 119+ / Safari 17.4+ 支持):
.accordion-item:has(> summary:not([open])) + .accordion-item {
margin-top: 0;
}
.accordion-item:not(:first-child):has(> summary[open]) ~ .accordion-item {
margin-top: 0;
}
/* 实际互斥需 JS,CSS 只能隐藏其他内容,但无法真正 close 其他 details */
所以:纯 HTML + CSS 实现“真手风琴”仍不可靠,<details> 天然适合多选折叠,不是单选。
summary里的图标旋转需要CSS控制open状态
想让 <summary> 右侧显示 ▶️ 或 ▼ 图标,并随展开/收起旋转,不能靠 JS 监听事件,得用 CSS 的 <details>[open] > summary::after 伪元素:
-
<summary>本身不能设content,必须写在父级<details>的条件选择器里 - 推荐用 SVG 或 Unicode 字符(如
\25BC▼),避免字体加载问题 - 旋转动画需显式声明
transition,否则切换生硬
示例:
details summary::after {
content: " ▶";
transition: transform 0.2s;
}
details[open] summary::after {
content: " ▼";
transform: rotate(0deg);
}无障碍与SEO注意事项
<details> 原生支持屏幕阅读器,但有两点容易忽略:
- 如果
<summary>文本不够描述性(比如只写“点击展开”),会影响可访问性——应写明内容主题,如“配置项说明” - 搜索引擎会索引
<details>内所有文本,无论是否open,这点和 JS 动态渲染不同 -
<summary>不支持tabindex,也不能放表单控件(会导致焦点行为异常)
移动端 Safari 对 <details> 的触摸反馈较弱,建议加 cursor: pointer 和轻微背景色变化提升可感知性。



















