弹窗内嵌套折叠不能用,因Safari和微信X5内核失效、状态不同步;应采用ul/li+checkbox+CSS方案,严格保证input与label紧邻、~选择器生效,并处理表单/视频隐藏陷阱及移动端布局安全。

弹窗内嵌套折叠展开,不能直接用 <details></details> 嵌套 —— Safari 和微信 X5 内核会直接失效,状态不同步是必然结果。
为什么 <details></details> 在弹窗里嵌套会出问题
HTML5 规范未定义 <details></details> 嵌套行为,浏览器实现不一致:Chrome/Firefox 表面能点开,但外层 <summary></summary> 的 toggle 事件监听不到子级状态变化;Safari(尤其是 ≤16.3)会忽略内层 open 属性,点击无响应;微信内置浏览器(X5 内核)则直接跳过整个内层结构,DOM 存在但交互不可用。更关键的是,<summary></summary> 必须是 <details></details> 的第一个子元素,而弹窗内容常由模板引擎动态插入,稍有空格或换行就会让 <summary></summary> 失效。
弹窗里真正可用的折叠方案:ul/li + checkbox + CSS
这是目前唯一能在弹窗中稳定支持多级折叠、记住展开状态、兼容触摸设备且无需 JS 初始化的方案。核心是利用 CSS 的 :checked 和兄弟选择器 ~ 驱动显隐:
-
<input type="checkbox" id="panel-1">必须放在最前,不能有换行或空格 -
<label for="panel-1">标题</label>必须紧邻其后,中间不能插任何节点(包括文本节点) -
<ul class="submenu"></ul>必须紧跟,且是它的直接兄弟元素 - CSS 规则必须写成:
input[type="checkbox"]:checked ~ .submenu { display: block; },不能用visibility或opacity - 缩进统一用
padding-left+border-left,避免margin-left导致 tab 键聚焦框偏移
弹窗内折叠内容含表单/视频时的隐藏陷阱
原生 <details></details> 收起时,内部 <input>、<video></video>、<iframe></iframe> 不会自动暂停或卸载。弹窗中若嵌套这类内容,用户关闭折叠面板后仍可能继续播放音频、提交表单或加载 iframe 资源。必须改用 JS 控制的 max-height 方案,并在收起时手动执行:
立即学习“前端免费学习笔记(深入)”;
-
video.pause()和video.currentTime = 0 -
iframe.contentWindow?.document?.write('')或移除src属性 - 清空表单控件值(如
input.value = ''),否则下次展开时残留上次输入 - 如果用
max-height动画,收起后务必清除行内style.maxHeight,否则后续scrollHeight测量会错乱
移动端弹窗折叠菜单必须强制收起子级
小屏下(@media (max-width: 768px))所有 .submenu 必须设为 display: none,且不能靠 JS 切换 —— 否则弹窗内容区会被严重挤压,甚至触发横向滚动。这不是“体验优化”,而是布局安全底线。尤其注意:
- 不要只靠
max-height: 0隐藏,它仍占流式布局空间 - z-index 层级要高于弹窗遮罩层,否则子菜单被盖住
- 键盘导航(Tab)必须能顺序进入每级
<label></label>和可聚焦子项,不能因display: none跳过 - 微信内嵌浏览器检测到
MicromessengerUA 时,应直接降级为<div> + <code><button></button>结构,并补全aria-expanded和aria-controls真正难的不是写几行 HTML,而是确保每级
input和label之间没有看不见的空白符,以及每次动态插入弹窗内容后,都重新校验 DOM 层级是否满足~选择器的严格要求。



















