在CSS的伪类选择器中,:focus和:focus-visible都用于匹配处于焦点状态的元素,但两者的设计目标和触发逻辑有本质区别,很多开发者在实际使用中容易混淆两者的适用场景。

:focus 伪类的基本特性
:focus是CSS中较早支持的伪类选择器,只要元素获得焦点就会触发匹配,无论焦点是通过什么方式获取的。常见的获取焦点的方式包括鼠标点击、键盘Tab键切换、触摸操作等。
它的触发范围非常广,几乎所有可交互元素在获得焦点时都会被:focus匹配到,比如<input>、<button>、<a>等元素。
下面是一个基础的:focus样式示例:
/* 所有获得焦点的元素都会应用这个样式 */
:focus {
outline: 2px solid #1890ff;
outline-offset: 2px;
}
:focus-visible 伪类的设计初衷
:focus-visible是后来新增的伪类选择器,它的核心目标是区分用户是通过键盘还是鼠标/触摸获取的焦点。只有当浏览器认为需要向用户展示焦点状态的时候,才会匹配这个伪类,通常对应键盘导航的场景。
这样设计的原因是,鼠标点击元素时用户本身已经知道元素被选中了,不需要额外的焦点轮廓提示,而键盘切换焦点时用户需要明确的视觉反馈,避免焦点丢失。
两者的核心区别对比
我们可以从触发条件、适用场景、浏览器支持三个维度对比两者的差异:
| 对比维度 | :focus | :focus-visible |
|---|---|---|
| 触发条件 | 元素获得焦点即触发,无论获取方式 | 仅当浏览器判定需要展示焦点时触发,通常是键盘操作 |
| 适用场景 | 需要所有焦点状态都生效的样式 | 仅需要键盘导航时展示的焦点样式 |
| 浏览器支持 | 所有主流浏览器均支持 | 现代主流浏览器支持,旧版IE不支持 |
实际代码示例演示差异
我们可以通过一个按钮的样式示例,直观看到两者的表现差异:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<style>
/* 鼠标点击和键盘切换都会生效 */
.test-btn:focus {
background-color: #e6f7ff;
}
/* 仅键盘切换焦点时生效 */
.test-btn:focus-visible {
outline: 2px solid #ff4d4f;
outline-offset: 4px;
}
</style>
</head>
<body>
<button class="test-btn">测试按钮</button>
<input type="text" class="test-input" placeholder="测试输入框">
</body>
</html>
在上面的代码中,当用鼠标点击按钮时,按钮会触发:focus的样式,背景变为浅蓝色,但不会触发:focus-visible的红色轮廓样式。当用键盘Tab键切换到按钮时,两个样式都会生效,按钮背景变浅蓝且出现红色轮廓。
最佳实践建议
在实际开发中,推荐的组合用法是:
- 如果需要重置所有焦点默认样式,可以先使用
:focus清除默认outline - 再使用
:focus-visible为键盘导航场景添加合适的焦点提示样式 - 对于需要兼容旧版浏览器的场景,可以添加
:focus作为降级方案
示例代码如下:
/* 清除默认焦点样式 */
:focus {
outline: none;
}
/* 键盘导航时的焦点样式 */
:focus-visible {
outline: 2px solid #1890ff;
outline-offset: 2px;
}
/* 兼容不支持:focus-visible的浏览器 */
@supports not selector(:focus-visible) {
:focus {
outline: 2px solid #1890ff;
outline-offset: 2px;
}
}
这样的写法既保证了键盘用户的焦点可感知性,又避免了鼠标操作时出现不必要的焦点轮廓,提升了整体的交互体验。
CSS:focus:focus-visible伪类选择器修改时间:2026-07-16 01:18:26