无法实现多步骤表单,因其仅支持独立折叠/展开,缺乏状态流转、数据暂存、顺序控制等核心能力;真需多步骤必须用 javascript 全程驱动逻辑, 仅可作视觉分组容器。

<details></details> 标签本身不能做多步骤表单——它只管单个折叠/展开,没有步骤状态、数据暂存、顺序控制或进度同步能力。真要做多步骤,得用 JavaScript 驱动逻辑,<details></details> 顶多当个「视觉分组容器」来收起非当前步的内容,但别指望它替代步骤管理。
为什么不能直接套用 <details></details> 实现多步骤
多步骤表单核心是「状态流转」:当前在哪步、上一步/下一步怎么走、字段校验、数据暂存、进度条更新、键盘导航支持……这些 <details></details> 一个都不提供。<details></details> 的 open 属性是独立布尔值,10 个 <details></details> 就是 10 个互不相干的开关,JS 不介入,它们永远无法形成「线性流程」。
常见错误包括:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 把每步包进一个
<details></details>,然后只靠open控制显隐,但没同步currentStep变量,导致后退时第 3 步仍开着、第 2 步却没激活 - 用
document.querySelector('details[open]')判断当前步——不可靠,用户可能手动右键“检查元素”改了 open 值,或 JS 异常中断后状态错乱 - 点击“上一步”只设
prevDetails.open = true,却忘了把后续所有details.open = false,视觉和逻辑脱节
用 <details></details> 当步骤容器时的 JS 控制要点
如果坚持用 <details></details> 包每步(比如为了语义化分组或移动端折叠体验),JS 必须全程接管状态,且严格遵循以下规则:
- 维护唯一可信源:
let currentStep = 0,所有 DOM 操作都基于它,而不是反向从 DOM 读取 - 切换步骤前先清空:遍历所有
<details></details>,统一设el.open = false,再对目标项设el.open = true - 禁用用户直接点击
<summary></summary>切换:给每个<summary></summary>绑定click事件并e.preventDefault(),否则会干扰 JS 管理的流程 - 键盘支持不能丢:监听
keydown(如 Enter/Space)时,同样走 JS 步骤跳转逻辑,而非依赖原生<details></details>行为 - 提交前校验必须在 JS 中统一做:不能只靠某步
<details></details>是否 open 来判断该步是否完成
比 <details></details> 更合适的多步骤实现方式
真正健壮的多步骤表单,推荐放弃用 <details></details> 承载步骤逻辑,改用语义更清晰、控制更直接的方式:
- 用
<section></section>或<div role="region"> 包每步,配合 <code>aria-hidden="true/false"控制显隐,JS 只需切换属性,不碰open - 进度条用
<progress value="2" max="4"></progress>,但value必须由 JS 动态赋值,不能写死 - 步骤导航用
<ol></ol>+aria-current="step",每项<li>对应一步,JS 更新时只改这个属性 - 数据暂存用
localStorage或内存对象,每次切步前调用函数收集当前步字段值,避免用户刷新丢失 - 若需折叠效果,CSS 控制
max-height和overflow即可,比强绑<details></details>更可控
最易被忽略的一点:多步骤不是「显隐切换」问题,而是「状态机」问题。哪怕只用三行 JS 维护 currentStep、校验函数和 DOM 同步,也比堆砌 10 个 <details></details> 却无状态管理来得可靠。别让标签的便利性掩盖逻辑缺失。










