summary:focus 样式不生效主因是 outline 被重置库清除或被显式设为 none 且未补替代样式,或受 pointer-events、display: contents、子元素抢占焦点等影响;应优先用 outline 微调,兼顾可访问性与多维提示,并注意 iOS Safari 兼容性。

details 标签本身不可聚焦,真正接收 Tab 键焦点的是其子元素 summary —— 你必须针对 summary 定制 :focus 样式,而不是 details。
为什么 summary:focus 样式有时不生效
常见原因不是写法错,而是被 CSS 重置或浏览器默认行为覆盖:
-
summary默认有outline: -webkit-focus-ring-color auto 1px(Safari/Chrome),但很多 CSS 重置库(如 normalize.css)会清掉outline,导致焦点“消失” - 写了
summary:focus { outline: none; }却没补替代样式,等于主动屏蔽键盘用户感知 -
summary被设了pointer-events: none或tabindex="-1",直接剥夺聚焦能力 - 父级
details用了display: contents,导致summary脱离渲染树,:focus失效
如何安全添加 focus 样式而不破坏可访问性
目标是让键盘用户清晰看到当前聚焦项,同时不干扰鼠标/触屏操作:
- 用
outline最稳妥:保留浏览器原生 focus ring 的语义和高对比度逻辑,仅微调颜色与偏移summary:focus { outline-color: #2563eb; outline-offset: 2px; } - 若需自定义轮廓(如圆角边框),必须加
outline: none后手动实现:summary:focus { outline: none; box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.3); } - 别只靠颜色变化:键盘用户可能色觉障碍,务必叠加形状、阴影或图标旋转等多维提示
details[open] summary:focus::before { content: "▼"; } - 测试时禁用鼠标,纯用 Tab + Shift+Tab 导航,确认每个
summary都能进入、停留、离开
移动端 Safari 的 focus 状态延迟问题
iOS Safari ≤15.4 中,summary 在首次 Tab 进入时可能不触发 :focus,尤其当它位于滚动区域外或刚动态插入 DOM 时:
立即学习“前端免费学习笔记(深入)”;
- 临时兜底:给
summary加tabindex="0"(虽然原生支持,但显式声明可提升兼容性) - 避免在
summary上使用transform: scale()或opacity: 0.99,这些会干扰 Safari 的焦点检测 - 监听
focusin事件而非仅依赖伪类:summary.addEventListener('focusin', () => summary.classList.add('focused')); - 注意:不要在
focusin回调里立即修改summary的display或visibility,否则焦点会丢失
最易被忽略的一点:即使你加了完美的 :focus 样式,如果 summary 内部嵌套了 button 或 a,焦点会落在子元素上,summary:focus 就永远不会匹配——这时得改用 summary:focus-within 或重构结构。



















