用户有很多种访问网站的方式,例如:鼠标、触摸设备、屏幕阅读器、键盘。在本文中,我们将了解有关焦点指示器的所有内容,如何设置它们的样式以及它们对许多用户的重要性。
在聚焦输入元素时是否见过蓝色轮廓?这是原生对焦点样式浏览器用来指示某个元素被聚焦的方式。
以上是 Chrome、Edge、Safari 和 Firefox 中输入元素的原生焦点样式。
此蓝色轮廓将显示所有交互元素。这包括 <a>
、<button>
和所有表单元素,如 <input>
和 <select>
元素。每个浏览器都有一个稍微不同的默认样式,因此您可能希望更改默认样式。
现在,我们知道什么是焦点指示器,让我们看看如何改变默认的样式。
a:focus {
outline: none;
background-color: #651787;
color: #fff;
}
在这里,我们使用 outline: none
删除默认的蓝色轮廓,同时更改背景颜色和接收焦点时元素的颜色。通过这种方式,用户仍然可以很容易地识别出元素当前的焦点,你可以根据设计进行匹配,而不是使用原生的蓝色轮廓。
这里要注意的一点是,当你改变颜色时,你应该检查颜色对比度是否足够。这对于视力低下的人来说尤其重要,但是颜色对比度差会影响到每个人。如果你曾经坐在阳光下上网,你就会知道拥有一个好的颜色对比度是多么重要,这样你才能看到屏幕上的内容。
是否想要设置聚焦元素的父元素的样式?
CSS 伪类 :focus-within
可以精确地实现这一点。
让我们看看如何使用它:
<form>
<label for="username">Username:</label>
<input id="username" type="text" />
<label for="password">Password:</label>
<input id="password" type="password" />
<input type="submit" value="Login" />
</form>
在这里,我们有一个基本的登录表单在 HTML。作为下一步,我们将使用 CSS 来创建一定的效果:
form {
padding: 10px;
position: relative;
overflow: hidden;
}
form:before {
content: '';
background: #ddd;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: -1;
transform: translateY(-100%);
transition: transform 260ms ease-out;
}
form:focus-within::before {
transform: translateY(0);
}
默认情况下,我们使用 :before
为表单创建背景,并使用 transform: translateY(-100%)
隐藏它。
一旦用户点击其中一个 input
元素,背景将从顶部移入。这是通过使用 form:focus-within::before
并将 translateY
设置为 0
来完成的。此外,我们使用 transition
使其成为平滑效果。
有时,使用 :focus
样式也会对鼠标/指针用户的用户体验产生副作用。以具有上一个/下一个控件的图像库为例。如果用户单击其中一个按钮,它们将聚焦,因此将显示聚焦样式。虽然这对键盘用户来说很好,但对鼠标/指针用户来说可能太多了。
在这里,如果用户使用鼠标或指针聚焦元素,我们将使用伪类显式删除焦点样式。这样,键盘用户仍然可以看到焦点指示器,而鼠标用户则看不到。太好了,问题解决了
在之前,你可能会使用以下错误的方法来修复这样的问题。
button:focus {
outline: none;
}
别在这样做了。这会删除键盘用户的焦点指示器,使您几乎无法使用图像库。
我们可以使用 :focus-visible
伪类,仅当用户使用键盘对焦元素时,才会显示对焦样式。
让我们来看看如何使用它:
/* 提供基本的焦点样式 */
button:focus {
...;
}
/* 删除鼠标用户的焦点样式 */
button:focus:not(:focus-visible) {
outline: none;
}
在这里,我们使用 :not
伪类来明确删除对焦样式,如果用户使用鼠标或指头对焦元素。这样,键盘用户仍将看到对焦指示器,而鼠标用户看不到。
以下是 focus-visible
的支持情况:
如果需要兼容低版本浏览器,你可以使用 polyfill
来支持在这些不支持的环境中运行该属性。
由于所有现代浏览器都支持 Grid 和 Flexbox,我们可以轻松地在 CSS 中重新排序元素。这是非常棒的,您可以实现出色的布局,但是在不更改元素本身顺序的情况下,在视觉上更改顺序也存在问题。
默认情况下,焦点顺序必须是有意义的,不然将有意想不到的影响。
让我用一个链接列表的例子来解释:
<ul>
<li><a href="#">One</a></li>
<li><a href="#">Two</a></li>
<li><a href="#">Three</a></li>
<li><a href="#">Four</a></li>
<li><a href="#">Five</a></li>
</ul>
默认情况下,这些链接的视觉顺序和选项卡顺序匹配。当使用 tab
键导航时,它将从 1
变为 2
,以此类推。
现在,让我们想象一下,我们想要直观地更改顺序,并将第三个元素移动到最后一个位置:
ul {
margin: 0;
padding: 0;
list-style: none;
display: flex;
flex-direction: column;
}
/* 目视将第三个元素移动到最后一个位置 */
li:nth-child(3) {
order: 1;
}
现在,第三个元素在视觉上处于最后一个位置,但选项卡顺序仍然是 1
、2
和 3
。
视觉顺序和键盘导航顺序不再匹配 ,这会使键盘用户无法使用这些东西。当你用 CSS 改变 order
时,你需要考虑这个问题,如果它仍然有意义的话,我们应该使用键盘进行测试。