details标签不管理缩进,缩进须用data-level属性配合padding-inline-start等逻辑属性显式控制,以确保RTL、打印、高对比度及键盘导航下均一致;直接嵌套会导致缩进失效、点击穿透与open状态不同步。

details 标签本身不管理缩进,只控制展开/折叠状态;缩进必须由 CSS 显式控制,且不能依赖 margin-left 这类物理方向属性——否则 RTL 页面、高对比度模式、打印样式全会错位。
为什么直接嵌套 details 会导致缩进失效
浏览器对嵌套的 details 不自动添加缩进,它只渲染语义结构。你看到“有缩进”,往往是父级 details 的 padding 或 margin 意外传递给了子级,或 CSS 选择器写成了 details details { margin-left: 20px; } 这种不可靠写法。
- 这种写法在 RTL 页面中会把内容推到屏幕外(
margin-left在 RTL 下仍往左推) - 键盘导航时焦点顺序可能跳过中间层级(因脱离文档流)
- 打印 PDF 或启用高对比度模式时,缩进常消失——这些环境会重置大部分内联样式和物理方向属性
用 data-level + padding-inline-start 控制缩进
给每层 details 加上 data-level="1"、data-level="2" 等明确层级标记,CSS 用逻辑属性适配所有书写方向:
<details data-level="1">
<summary>一级项</summary>
<details data-level="2">
<summary>二级项</summary>
<p>内容</p>
</details>
</details>
CSS 写法:
立即学习“前端免费学习笔记(深入)”;
[data-level="2"] { padding-inline-start: 1.5rem; }
[data-level="3"] { padding-inline-start: 3rem; }
[data-level="4"] { padding-inline-start: 4.5rem; }
-
padding-inline-start在 LTR 下等价于padding-left,在 RTL 下自动变成padding-right,无需额外判断 - 避免用
transform: translateX()或position: relative缩进——它们会让元素脱离文档流,破坏屏幕阅读器遍历顺序 - 不要用
ul包裹details来“借”默认缩进,那会混淆语义(列表 ≠ 可折叠容器)
嵌套太深时 details 的交互缺陷
原生 details 在超过 3 层嵌套后,会出现 Safari 中点击穿透、焦点卡死、open 属性不同步等问题。这不是样式问题,而是规范未定义多层独立状态管理。
- 点开第 4 层时,第 2 层可能意外收起(尤其在 iOS Safari 16.4 之前)
-
summary默认点击热区太小,移动端易误触;必须加padding扩展可点击区域(至少16px) - 若需支持键盘用户按
Tab进入后用Space或Enter切换,别在summary里塞button——会覆盖原生行为
真正难的不是写几行 details 嵌套,而是让每一层的缩进在 RTL、打印、高对比度、键盘导航下都保持一致——这要求放弃“看起来像”的视觉思维,转而依赖语义标记与逻辑属性。漏掉 data-level 或写错 padding-inline-start,后面所有兼容性补丁都白搭。



















