问题背景
很多网站在设计时为了追求视觉简洁,会直接使用 *:focus { outline: none; } 移除所有焦点轮廓。这种做法对鼠标用户影响不大,但对键盘用户而言是灾难性的——他们完全无法感知当前聚焦在哪个可交互元素上。
:focus-visible 伪类的出现解决了这个问题:它只在键盘导航时显示焦点样式,鼠标点击时不会出现蓝色边框,兼顾了美观和可访问性。
核心实现
在全局样式中为所有可交互元素添加自定义焦点指示器:
1*:focus-visible {
2 outline: 2px dashed var(--color-primary, #3182ce);
3 outline-offset: 3px;
4 box-shadow: 0 0 0 4px rgba(49, 130, 206, 0.15);
5 border-radius: 4px;
6 transition: outline-offset 0.15s ease;
7}
参数说明:
outline: 2px dashed— 虚线边框比实线更柔和,不会显得突兀outline-offset: 3px— 让轮廓与元素边缘保持距离,避免遮挡内容box-shadow— 叠加半透明光晕,增强视觉层次border-radius— 圆角与元素自身圆角保持一致
暗色模式适配
使用 data-theme 属性区分亮暗主题下的焦点颜色:
1[data-theme="dark"] *:focus-visible {
2 outline-color: var(--color-primary-dark, #63b3ed);
3 box-shadow: 0 0 0 4px rgba(99, 179, 237, 0.25);
4}
暗色背景下需要提高光晕的亮度和对比度,确保键盘用户依然能清晰辨识焦点位置。
特殊元素处理
对于链接、按钮等高频交互元素,可以进一步微调:
1a:focus-visible {
2 outline-offset: 2px;
3 text-decoration: underline;
4}
5
6button:focus-visible,
7input:focus-visible,
8select:focus-visible,
9textarea:focus-visible {
10 outline-offset: 2px;
11 box-shadow: 0 0 0 3px rgba(49, 130, 206, 0.2);
12}
效果对比
相比于浏览器默认的 outline(通常是黑色或蓝色实线),自定义方案的优势在于:
| 维度 | 浏览器默认 | 自定义方案 |
|---|---|---|
| 样式 | 实线矩形框 | 虚线边框 + 光晕 |
| 暗色模式 | 不自动适配 | 通过 CSS 变量自动切换 |
| 视觉美观 | 较为突兀 | 与主题风格统一 |
| 可见性 | 低对比度场景不可见 | 多层效果保证可见 |
兼容性说明
:focus-visible 在现代浏览器中已获得广泛支持(Chrome 86+、Firefox 85+、Safari 15.4+)。对于需要兼容旧版浏览器的场景,可以结合 :focus 作为降级方案:
1*:focus {
2 outline: 2px dashed var(--color-primary);
3 outline-offset: 3px;
4}
5*:focus:not(:focus-visible) {
6 outline: none;
7}
这样既保证了键盘用户的体验,又避免鼠标点击时出现多余焦点框。
留言评论
期待你的想法评论加载中