唯一合法的选择器是details > *:not(summary),所有样式必须作用于details的子元素且排除summary;max-height动画需配合overflow: hidden,终值须为具体像素值;嵌套details需用语义类名隔离作用域;扩大summary点击区应避免破坏语义。

details > *:not(summary) 是唯一合法的选择器目标
浏览器不认 ::details-content 这种伪元素——它根本不存在。所有对折叠内容区域的样式控制,必须落在 details 的子元素上,且排除 summary。常见错误是写 details::content 或 details > div(没加 :not(summary) 会导致 summary 也被误选)。
正确写法只有:details > *:not(summary) 或更稳妥的 details > :first-child + *(利用 DOM 顺序)。如果内容区有固定结构,比如总用 .content 类,就直接写 .content,别强依赖标签名。
- 别给
details自身设overflow: hidden——这会裁剪掉展开后的内容,尤其当内容有绝对定位或浮动时 -
details > *:not(summary)默认是display: block,但 Safari 有时会额外加 margin,建议显式重置:margin-top: 0 - 若内容里有
<video></video>或<iframe></iframe>,收起时它们仍在运行;需 JS 监听toggle事件手动pause()或src = ""
max-height 动画必须配 overflow: hidden 才生效
直接对 details > *:not(summary) 做 height 或 opacity 过渡,动画会卡顿或跳变。真正能平滑过渡的是 max-height,但它有个硬性前提:目标元素必须设 overflow: hidden,否则浏览器无法触发重排计算高度变化。
典型写法:
立即学习“前端免费学习笔记(深入)”;
details > *:not(summary) {
overflow: hidden;
max-height: 0;
transition: max-height 0.3s ease, opacity 0.2s ease;
}
details[open] > *:not(summary) {
max-height: 500px; /* 必须是具体像素值,不能是 auto */
opacity: 1;
}-
max-height终值要足够大(如500px),覆盖所有可能内容高度;设太小会导致文字被截断 - 设
max-height: 0时,内容不可见,但依然参与文档流,所以padding和border仍占空间——若要彻底“消失”,得配合opacity: 0和pointer-events: none - 不要用
visibility: hidden替代max-height: 0,它不触发重排,动画无效
嵌套 details 时,子级内容样式容易被父级 overflow 截断
当 details 里再套 details,父级的 max-height + overflow: hidden 会把子级 summary 的点击热区压扁,甚至让子级箭头消失。这不是 bug,是 CSS 层叠规则的自然结果。
解决方式不是去掉父级 overflow,而是隔离作用域:
- 给每层
details加语义类名,如<details class="faq-section">、<details class="faq-item"> - 用属性选择器限定范围:
.faq-section > *:not(summary)和.faq-item > *:not(summary)分开写 - 子级
summary若需要更大点击区域,用padding+display: block,别碰position: relative——它可能让伪元素错位
移动端点击热区小、误触多,别只靠 summary padding
原生 summary 的可点击区域仅限文字+默认 marker 区域,左右留白点不中。加 padding 只扩大视觉范围,不扩大触发区。很多团队因此在 summary 外包一层 div 并监听 click,但这破坏了语义和键盘支持。
更稳妥的做法:
- 用
summary::before占位并设pointer-events: none,让点击穿透到summary根节点 - 确保
summary本身有tabindex="0"(默认已有),且未被pointer-events: none阻断 - 真要扩大热区,用
label包裹summary(需同步for和id),但注意summary必须仍是details的第一个子元素——label不能作为父容器
最易被忽略的点:Safari 对 summary 内部 display: flex 的点击支持不稳定,哪怕只是加个图标对齐,也建议用 text-align 或 margin 替代。


















