Chrome中:focus表现不一致的根本原因是未控制好“谁在聚焦”和“焦点样式被谁覆盖”;需统一border声明、确保JS聚焦时机合法、正确使用:focus-visible并避免无效语法。
Chrome 里 :focus 表现不一致,根本原因不是浏览器 Bug,而是你没控制住「谁在聚焦」和「焦点样式被谁覆盖」这两件事。
这不是 :focus 失效,是 Chrome 默认的 outline 在干扰。它会在点击后短暂显示,然后被后续样式或 UA 样式覆盖掉——尤其当你写了 outline: none 却没补全 border 或其他视觉反馈时,就会出现“闪一下又消失”的错觉。
outline 是否真被清除,且 border、box-shadow 等替代样式已生效input:focus { outline: none; border-color: #007bff; }——如果默认状态没定义 border,非聚焦态可能直接退化为 border: 0
input { border: 1px solid #ced4da; },再在 :focus 中仅改颜色或加阴影常见于 JS 动态插入元素或 React/Vue 组件中。Chrome 要求 focus 必须发生在「用户可感知的交互上下文」内,否则会静默拒绝。
focus() 执行前,元素已挂载、display 不为 none、且未设 disabled
setTimeout 或事件回调中调用,建议包一层 requestAnimationFrame,等渲染帧就绪再聚焦:focus 规则默认不生效;必须把样式放进 <style> 标签内,或用 ::slotted(input:focus)
Chrome(86+)同时支持两者,但它们的匹配逻辑不同::focus 是“只要获得焦点就匹配”,:focus-visible 是“只在键盘触发时才匹配”。如果你写了两条规则且特异性相同,后声明的会覆盖前一条。
input:focus { outline: none; } input:focus-visible { outline: 2px solid #007bff; } —— 若用户鼠标点击,:focus 生效但 :focus-visible 不匹配,结果是没 outlineinput:focus { outline: none; } input:focus-visible { outline: 2px solid #007bff; outline-offset: 2px; },并确保有降级 fallback(如引入 js-focus-visible):focus 和 :focus-visible 混在同一个选择器里,比如 input:focus:focus-visible,这是无效语法真正难处理的不是 Chrome 本身,而是你没意识到:它的 :focus 行为始终严格遵循规范,但你的样式层、JS 聚焦时机、DOM 结构、甚至框架的渲染节奏,都在悄悄改写它的表现边界。