summary 抖动源于 details 状态切换时的隐式重排,而非 box-sizing;应设 display: block、min-height 锁定 baseline,禁用 outline,确保 details{height:auto},并剥离 inline 干扰。

直接给 summary 加 box-sizing: border-box 不能解决问题——跳动根源不在它自身尺寸计算,而在浏览器对 details 内部重排的不可控触发。关键得切断默认布局干扰链。
为什么 summary:hover 或 open 状态下会抖动
抖动不是动画导致的,而是 details 元素在状态切换时,内部触发了一次隐式重排(reflow):浏览器会临时重算 summary 的行高、内联尺寸、基线位置,尤其当它包含 inline 元素、图标或设置了 line-height/vertical-align 时,这种重排会牵连周围盒模型边界,造成视觉“抽搐”。
常见错误现象包括:
-
summary左侧图标轻微上移或下沉 - 展开瞬间文字行距突变
- 父容器高度微幅跳动(尤其嵌套在 flex 容器中)
用 display: block + min-height 锁定 baseline
核心思路是让 summary 脱离 inline 上下文,消除基线对齐带来的不确定性。不依赖 line-height 做垂直居中,改用块级控制。
实操建议:
- 强制
summary { display: block; },断开与文本流的基线耦合 - 设置
min-height(如min-height: 44px),确保内容区有稳定高度锚点 - 若需垂直居中文字,用
display: flex; align-items: center;替代line-height - 避免在
summary上设vertical-align,它只对 inline 元素生效,且在状态切换时易被重置
禁用 outline 和 focus 样式干扰
移动端点击或键盘聚焦时,summary 可能被加上浏览器默认 outline,而 outline 不参与盒模型计算,但渲染时机晚于 layout,会造成“先跳再加边框”的错觉。
实操建议:
- 显式重置:
summary:focus { outline: none; } - 若需可访问性焦点指示,改用
box-shadow: 0 0 0 2px #007bff;,它走的是绘制层,不影响 layout - 搭配
summary { cursor: unset; }(见知识库中移动端闪烁方案),进一步减少触摸反馈层介入
details 元素本身要设 height: auto
某些 UI 框架或重置样式会把 details 设为 height: 0 或 min-height: 0,这会让浏览器在 open 状态切换时反复计算高度,加剧抖动。
必须确保:
-
details { height: auto !important; }(仅当被第三方样式覆盖时加!important) - 不要给
details设固定height或max-height,除非你手动控制展开逻辑 - 若用 CSS 控制展开/收起(如
details[open] > * { max-height: 500px; }),务必配合overflow: hidden和transition: max-height 0.3s ease-in-out,而非依赖浏览器原生行为
真正难处理的点在于:抖动往往只在特定组合下出现——比如 summary 里嵌了 SVG 图标 + 文字 + flex 容器 + 外层用了 grid。这时候光调 box-sizing 或 display 不够,得一层层剥离渲染上下文,从 details 根节点开始确认它的尺寸是否被父级约束、是否触发了 BFC 边界重算。最稳的做法,是把 summary 当作纯块级触发器,内容区域全交给子元素承载,自己只管尺寸和交互态。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











