和是HTML5原生语义化折叠组件,无需JS即可实现点击展开/收起,自带键盘可访问性(空格/回车触发)和屏幕阅读器支持;必须为的第一个子元素,加open属性可默认展开。

用details/summary替代手写折叠面板脚本
浏览器原生支持的 details 元素能直接实现点击展开/收起,无需监听 click、操作 display 或 max-height 动画。它自带语义、键盘可访问(空格/回车触发)、且无 JS 依赖。
常见错误是强行用 div + onclick 模拟,结果漏掉焦点管理、不响应键盘、屏幕阅读器不可读。更糟的是,为“平滑动画”硬加 CSS 过渡——details 本身不支持 transition,只能靠 summary 后元素用 max-height + overflow 做 hack,反而增加重排开销。
实操建议:
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
- 直接写
<details><summary>标题</summary><p>内容</p> <p><span>立即学习</span>“<a href="https://pan.quark.cn/s/cb6835dc7db1" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">前端免费学习笔记(深入)</a>”;</p></details>,默认关闭;加open属性可默认展开 - 若需动画,只对
details[open] > *内的子元素做max-height过渡,且设固定值(不能用auto) - 避免在
summary里嵌套按钮或链接——会干扰原生行为,改用纯文本 + CSS 样式控制外观
用dialog替代 div + 手动遮罩层脚本
dialog 是现代浏览器(Chrome 97+、Firefox 98+、Safari 15.4+)原生模态框元素,调用 showModal() 自动处理焦点锁定、背景滚动禁用、ESC 关闭、Backdrop 样式隔离等逻辑。
手写遮罩层常踩的坑:忘记 inert 或 aria-hidden,导致屏幕阅读器仍可聚焦背景内容;手动计算 scrollbarWidth 补偿导致布局抖动;Backdrop 点击穿透未拦截;关闭后焦点未回归触发元素。
实操建议:
- 结构必须为
<dialog><p>内容</p> <p><span>立即学习</span>“<a href="https://pan.quark.cn/s/cb6835dc7db1" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">前端免费学习笔记(深入)</a>”;</p></dialog>,不能用div[role="dialog"]伪替代 - 用
dialog.showModal()触发,dialog.close()关闭;close事件可监听,但不要依赖click外部区域——原生已处理 - Backdrop 样式通过
dialog::backdrop控制,无需额外div;注意 Safari 对backdrop-filter支持有限 - 旧浏览器降级方案:只用
@supports not (display: dialog)包裹样式,JS 中检测typeof HTMLDialogElement !== 'undefined'再启用
用input type="date"等语义化控件替代自定义日历组件
原生表单控件(type="date"、"time"、"color"、"range")由系统渲染,自动适配平台交互习惯(如 iOS 滚轮、Android 日历弹窗),且无需加载 KB 级 JS 库。
问题常出在「过度定制」:为统一视觉强覆写所有样式,结果破坏可访问性(如移除 appearance: none 后未补全 focus outline);或监听 input 频繁触发格式校验,造成输入卡顿;更常见的是忽略时区与本地化——valueAsDate 返回的是本地时间,但提交时按 ISO 8601 发送,服务端若未处理时区偏移,数据就错。
实操建议:
- 优先用原生控件,仅在必要时用
appearance: none调整外观,但必须保留:focus-visibleoutline 和cursor: pointer - 校验放在
submit事件而非input,避免高频触发;用checkValidity()+setCustomValidity()做轻量反馈 - 日期类字段,前端显示用
toLocaleDateString(),提交值保持原生value(ISO 格式),由后端解析时区
为什么这些替代方案容易被忽略
不是因为功能弱,而是它们不满足「完全可控」的错觉——开发者习惯用 JS 精确干预每一步,却忽略了浏览器原生实现已覆盖 90% 的通用场景,且经过数年性能与无障碍打磨。
真正难的从来不是“怎么让一个折叠面板动起来”,而是“当用户用键盘 Tab 进入、用 VoiceOver 朗读、在 200% 缩放下点击、或网络延迟 2s 时,它是否依然可用”。原生标签把这部分复杂度封装掉了,但需要你放弃一部分控制权,并认真读 MDN 上每个属性的兼容性备注和可访问性影响。


















