input:focus 的 border-color 无效是因默认 outline 层级更高,需加 outline: none; 并用 box-shadow 替代;应配合 :focus-visible 提升可访问性,父容器需设 tabindex="-1" 才支持 :focus-within。

直接写 input:focus { border-color: #007bff; } 通常没效果——浏览器默认的 outline 会盖住边框变化,必须显式处理。
为什么 border-color 改了却看不见
Chrome、Firefox 默认给聚焦的 input 加一层 outline(通常是蓝色或黑色外发光),它绘制层级高于 border,所以即使你改了 border-color,也被 outline 遮住了。常见现象是:鼠标点进去,只看到难看的双轮廓(边框+外发光)。
- 必须加
outline: none;才能让border-color可见 - 但不能只删
outline就完事——这会破坏键盘用户的可访问性 -
border-style必须是solid或dashed等可动画值;如果还是none,border-color即使生效也看不到 - 推荐初始样式就写全:
border: 1px solid #ced4da;,再在:focus里只改border-color
用 box-shadow 替代 outline 更安全
box-shadow 不占布局空间、可精确控制、支持 transition,且对屏幕阅读器和键盘导航用户友好。它不会干扰 border 的视觉表现,也不像 outline 那样容易被系统强制覆盖。
- 写法示例:
box-shadow: 0 0 0 2px rgba(0, 123, 191, 0.25); - 这个值模拟了原生
outline的“环形高亮”,但更可控 - 务必配合
outline: none;,否则box-shadow和outline会叠加出奇怪效果 - 透明度建议设为
0.2–0.3,避免过重遮挡文字
别只靠 :focus,加 :focus-visible 做渐进增强
:focus 在鼠标点击和键盘 Tab 进入时都会触发,但鼠标用户通常不需要额外高亮。用 :focus-visible 能区分交互方式:只在键盘导航时显示强反馈,鼠标点击则保持简洁。
- 基础组合写法:
input:focus { outline: none; }input:focus-visible { box-shadow: 0 0 0 2px rgba(0, 123, 191, 0.25); }- Safari 15.4+ 才支持
:focus-visible,旧版本会回落到纯:focus,所以:focus规则仍需保留 - 不建议仅用
:focus-visible覆盖全部逻辑,它不是:focus的替代品,而是补充
:focus-within 想高亮整个表单区域?先确认父容器能“听”到焦点
把 :focus-within 写在 input 自身上永远无效——它只能加在父容器上,且该容器必须处于“可聚焦上下文”中。一个纯 <div> 默认无法监听后代焦点。
<ul>
<li>正确写法:<code><div class="form-group" tabindex="-1"><input></div>
tabindex="-1" 不影响 tab 顺序,只赋予监听能力<form></form> 加 :focus-within,否则点按钮也会触发,容易误高亮:focus-within 规则里改 height、margin 或 display,这些会引发重排,导致内容跳动:focus-within,但视口还没稳定,可能错位真正容易被忽略的不是怎么写样式,而是:父容器有没有 tabindex="-1"、子元素是否真能获得焦点、box-shadow 的透明度有没有压住文字、以及旧版 Safari 下要不要 JS fallback。这些细节一漏,高亮就变成“看起来写了,但就是不生效”。











