CSS `:focus-visible` (焦点可见性) 与无障碍性

各位观众,晚上好!今天咱不整虚的,直接上干货,聊聊CSS里一个既实用又有点“傲娇”的属性::focus-visible。这玩意儿跟无障碍性(Accessibility,简称A11y)那可是有着千丝万缕的联系。别看名字长,其实理解起来并不难,保证你听完之后,腰不酸了,腿不疼了,键盘敲得更带劲了!

第一回合:什么是:focus? 为什么我们需要:focus-visible

咱们先来复习一下:focus这个老朋友。在CSS里,:focus 伪类用于选择当前获得焦点的元素。简单来说,就是你用鼠标点了一下,或者用Tab键切换到的那个元素。

<button>点我!</button>
<input type="text" placeholder="请输入内容">
button:focus {
  outline: 2px solid blue; /* 默认的焦点样式,通常是蓝色边框 */
}

input:focus {
  border: 2px solid green; /* 自定义的焦点样式 */
}

这段代码的意思是,当按钮或者输入框获得焦点时,会分别显示蓝色边框和绿色边框。这很棒,对吧?至少你知道自己当前操作的是哪个元素。

但是! 问题来了。:focus 伪类会无差别地对所有获得焦点的元素应用样式。这意味着,无论你是用键盘还是鼠标点击,焦点样式都会出现。这在某些情况下是没问题的,但有些时候,却会显得很突兀,甚至影响用户体验。

想象一下,你用鼠标点击一个按钮,按钮周围突然出现一个粗糙的蓝色边框。如果你是用键盘操作,这当然很有用,但如果你是用鼠标,这个边框就显得有点多余了,因为它破坏了按钮原有的设计。

这就是:focus-visible登场的原因!它就像一个更聪明的:focus,只有当浏览器判断当前焦点是通过键盘等非鼠标方式获得时,才会应用样式。

第二回合::focus-visible怎么用?

:focus-visible的用法和:focus几乎一样,只是它会更“挑剔”一些。

button:focus-visible {
  outline: 2px solid red; /* 只有键盘导航时才显示红色边框 */
}

button:focus {
  outline: none; /* 移除默认的焦点样式,避免与:focus-visible冲突 */
}

这段代码的意思是,当按钮通过键盘获得焦点时,才会显示红色边框。如果你用鼠标点击按钮,就不会有任何焦点样式。

关键点: 通常,我们会先移除默认的:focus样式,然后用:focus-visible提供更友好的焦点指示。

兼容性问题:

需要注意的是,:focus-visible并不是所有浏览器都支持。为了解决兼容性问题,我们可以使用一个polyfill(垫片)。

<script src="https://unpkg.com/[email protected]/dist/focus-visible.min.js"></script>

只需要在你的HTML文件中引入这个脚本,就能让不支持:focus-visible的浏览器也能正常工作。

第三回合::focus-visible与无障碍性(A11y)

这才是今天的重头戏!为什么说:focus-visible与无障碍性息息相关呢?

对于依赖键盘进行导航的用户(例如,视力障碍者),清晰的焦点指示至关重要。他们需要知道当前焦点在哪里,才能顺利地浏览和操作网页。

:focus-visible让开发者能够更精确地控制焦点样式,只在需要的时候显示焦点指示,从而提高键盘用户的体验。

举个例子:

假设我们有一个导航菜单:

<nav>
  <ul>
    <li><a href="#">首页</a></li>
    <li><a href="#">产品</a></li>
    <li><a href="#">关于我们</a></li>
    <li><a href="#">联系我们</a></li>
  </ul>
</nav>

如果直接使用:focus,当你用鼠标点击链接时,也会出现焦点样式,这可能会影响导航菜单的美观。

nav a:focus {
  outline: 2px solid orange; /* 鼠标点击也会显示橙色边框 */
}

更好的做法是使用:focus-visible

nav a:focus {
  outline: none; /* 移除默认的焦点样式 */
}

nav a:focus-visible {
  outline: 2px solid orange; /* 只有键盘导航时才显示橙色边框 */
}

这样,只有当你用Tab键在导航链接之间切换时,才会显示橙色边框,鼠标点击则不会。

第四回合::focus-visible的进阶用法

:focus-visible不仅仅可以用来显示边框,还可以用来改变元素的背景颜色、文字颜色、阴影等等。

button:focus-visible {
  background-color: lightblue;
  color: black;
  box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
}

这段代码的意思是,当按钮通过键盘获得焦点时,背景颜色会变成浅蓝色,文字颜色会变成黑色,并且会添加一个阴影。

更高级的技巧:与JavaScript结合

有时候,我们需要根据用户的交互方式来动态地改变焦点样式。例如,我们可以使用JavaScript来检测用户是否使用键盘进行导航,然后添加或移除一个CSS类。

document.addEventListener('keydown', function(event) {
  if (event.key === 'Tab') {
    document.body.classList.add('keyboard-navigation');
  }
});

document.addEventListener('mousedown', function() {
  document.body.classList.remove('keyboard-navigation');
});

这段JavaScript代码的意思是,当用户按下Tab键时,会在body元素上添加一个keyboard-navigation类。当用户点击鼠标时,会移除这个类。

然后,我们可以在CSS中使用这个类来控制焦点样式:

button:focus {
  outline: none; /* 移除默认的焦点样式 */
}

body.keyboard-navigation button:focus {
  outline: 2px solid purple; /* 只有在键盘导航模式下才显示紫色边框 */
}

这样,我们就可以根据用户的交互方式,动态地显示或隐藏焦点样式。

第五回合::focus-visible的最佳实践

  • 始终提供清晰的焦点指示: 无论你使用什么样式,都要确保焦点指示足够明显,能够让用户清楚地看到当前焦点在哪里。
  • 避免使用outline: none; 除非你有充分的理由,否则不要移除默认的焦点样式。outline虽然看起来不太美观,但它对于键盘用户来说非常重要。如果你要自定义焦点样式,可以使用:focus-visible来代替。
  • 测试你的网站: 使用键盘进行导航,确保焦点指示在所有元素上都能正常工作。
  • 考虑对比度: 确保焦点指示的颜色与背景颜色有足够的对比度,以便视力障碍者能够看到。
  • 保持一致性: 在整个网站中使用一致的焦点样式,避免让用户感到困惑。

第六回合:常见问题及解答

问::focus-visible:focus-within有什么区别?

答::focus-visible用于选择当前获得焦点的元素。:focus-within用于选择包含获得焦点的元素的父元素。例如,如果一个输入框在一个<div>元素中,当输入框获得焦点时,:focus-visible会选择输入框,:focus-within会选择<div>元素。

问:我可以只使用:focus-visible,而不使用:focus吗?

答:可以。但是,这样做可能会导致某些浏览器无法显示焦点样式。为了保证兼容性,最好同时使用:focus:focus-visible,并使用:focus来移除默认的焦点样式。

问::focus-visible会影响网站的性能吗?

答::focus-visible本身不会对网站性能产生明显的影响。但是,如果你使用了大量的JavaScript代码来动态地改变焦点样式,可能会影响性能。

第七回合:总结

:focus-visible是一个非常有用的CSS伪类,它可以让我们更精确地控制焦点样式,提高键盘用户的体验。虽然它不是万能的,但它确实是构建无障碍网站的重要一步。

记住,无障碍性不仅仅是为残疾人设计的,它是为所有人设计的。一个易于使用的网站,对所有人都有好处。

希望今天的讲座对你有所帮助。记住,多实践,多思考,你也能成为:focus-visible的高手!

祝大家编程愉快!下次再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注