details标签加open属性即可默认展开,浏览器只检测属性存在与否;正确写法是<details open>,错误写法如open="false"仍会展开;JS操作应使用el.open=true/false或toggleAttribute,CSS需用details[open]选择器。

details标签加open属性就能默认展开,别写值
直接在<details>标签上写open即可,默认展开;浏览器只检测这个属性是否存在,不解析等号右边的任何内容。
常见错误写法:<details open="false">、<details open="">、<details open="0">——这些全部等效于展开,因为属性名出现了。
- 正确默认展开:
<details open><summary>标题</summary><p>内容</p></details></li> <li>正确默认收起:<code><details><summary>标题</summary><p>内容</p></details></li> <li>服务端渲染或静态 HTML 场景下,这是最轻量、最可靠的方式,无 JS 依赖</li> </ul> <H3>JavaScript 动态设 open 状态,必须操作 DOM 属性,不是 setAttribute</H3> <p><code>el.open = true
或el.open = false才是正确写法;用setAttribute('open', ...)会把属性写进 HTML,导致“存在即展开”,哪怕你传的是"false"。容易混淆的点:
el.hasAttribute('open')查的是原始 HTML 字符串,而el.open是当前 DOM 状态,两者不同步。立即学习“前端免费学习笔记(深入)”;
- 初始没写
open:两者都是false - 执行
el.open = true后:el.open变true,但hasAttribute仍为false - 推荐切换方式:
el.toggleAttribute('open'),语义清晰且自动同步 HTML 和 DOM
CSS 响应展开状态只能用
details[open]选择器不能用
details[open="true"]或details:not([open])这类带值的写法——open是布尔属性,浏览器根本不解析它的值。想控制箭头旋转、内容显隐、边框颜色等,都得靠这个选择器:
details summary::after { content: "▼"; transition: transform 0.2s; } details[open] summary::after { content: "▲"; transform: rotate(180deg); }注意:
details[open]匹配的是 DOM 中实时的open布尔值,哪怕这个值是 JS 设置的,CSS 也能响应,但前提是元素已挂载且样式表已加载。动画实现时,open 属性本身不触发 transition
open属性只是个开关信号,浏览器对<details>的原生展开/收起是硬切换,没有过渡效果。要加动画,必须绕过它,用max-height+overflow模拟。关键细节:
- 初始设
.content { max-height: 0; overflow: hidden; transition: max-height 0.3s; } - 在
toggle事件里读scrollHeight,但得先确保元素可见(display: block),否则返回0 - 展开逻辑要分两步:先设目标
max-height→ 下一帧再设el.open = true;收起则反过来 - localStorage 恢复状态必须在动画初始化前完成,否则
el.open = true会跳过你的 CSS 过渡
最易被忽略的是 scrollHeight 读取时机和 toggle 事件里 DOM 渲染的异步性——状态变了,但样式还没应用,直接设 height 容易错位或闪动。
- 初始没写



















