默认展开只需写open属性,不带等号或值;js控制须用el.open=true/false,css用details[open]选择器,监听状态变化用toggle事件。

details默认展开只写open,多一个字符都错
想让<details></details>一打开就展开,直接加open属性就行——不带等号、不带引号、不带任何值。浏览器只认“有没有”,不解析右边写了啥。
-
<details open><summary>标题</summary>内容</details>→ 正确,默认展开 -
<details open="false"></details>、<details open=""></details>、<details open="0"></details>→ 全部强制展开(因为属性存在) -
<details></details>→ 默认收起(唯一安全的“关闭”写法)
这是 HTML 规范定义的布尔属性行为,不是 bug,是标准。写错值不会报错,但结果和你预期相反。
JS动态控制open状态必须改el.open,不是setAttribute
用 JavaScript 切换时,必须读写 DOM 元素的 open 属性(它返回布尔值),而不是操作 HTML 属性。
- ✅ 正确:
el.open = true、el.open = false、console.log(el.open) - ❌ 错误:
el.setAttribute('open', 'false')→ 实际触发展开(属性被写入,存在即生效) - ⚠️ 注意:
el.hasAttribute('open')和el.open不等价:初始没写open时两者都是false;但执行el.open = true后,hasAttribute仍返回false(HTML 源码没变)
CSS响应展开状态只能用details[open]选择器
想根据展开/收起改样式(比如箭头方向、内容高度),必须用属性选择器 details[open]。它响应 DOM 属性变化,零延迟、原生支持。
- ✅ 正确:
details[open] summary::after { content: "▲"; } - ✅ 正确:
details:not([open]) .content { max-height: 0; overflow: hidden; } - ❌ 错误:
details[open="false"]→ 浏览器根本不解析值 - ❌ 错误:
details.open→open不是 class,没有这个类名
别靠 JS 手动加 class,会破坏语义和可访问性;也别用 [open="true"] 这类写法,无效。
监听展开/收起变化只能用toggle事件
<details></details> 没有 change 事件。用户点击、键盘触发(空格/回车)或 JS 修改 el.open,都会派发 toggle 事件,且此时 el.open 已是最新的布尔值。
- ✅ 正确:
el.addEventListener('toggle', () => console.log(el.open)) - ❌ 错误:
el.addEventListener('change', ...)→ 根本不会触发 - ❌ 错误:给
<summary></summary>绑click→ 无法捕获 JS 触发的状态变更,且干扰键盘和屏幕阅读器行为
真正容易被忽略的是:toggle 在状态变更后才派发,el.open 是最终值;但首次加载页面时不会触发该事件——如果你依赖初始状态做逻辑,得单独读取 el.open。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











