通过 CSS outline: none;
从可交互元素(例如按钮)中删除轮廓一直是一种常见做法,因为大多数时候它看起来与品牌无关,但它阻碍了可访问性并使依赖在键盘导航上。
问题是我还没有找到一种简单的方法来区分鼠标/键盘之间的焦点事件源,并且单击以及键盘选项卡元素将触发焦点状态。
我知道这个问题一直是个hot topic,但是大多数来源已经有好几年了,所以我将展示我发现的关于如何实现仅键盘焦点的主要 4 种方法,每种方法都有自己的优缺点:
优点:解决了问题。
缺点:设计选项有限。
button {
width: 180px;
height: 60px;
background: #999;
border: none;
}
button:focus,
button:hover {
outline: 5px solid green;
}
<button>Click or Tab me!</button>
data-focus-method
属性。 what-input 也非常有名,与其他各种 polyfills 一起做得很好。优点:可以在所有浏览器中正常运行,无论设计如何都可以实现。
缺点:需要额外的 http 请求来获取 .js 文件,与其他解决方案相比,JS 对性能的影响更大。
ally.style.focusSource().current()
button {
width: 180px;
height: 60px;
background: #999;
border: none;
outline: none;
}
html[data-focus-source="key"] button:focus {
outline: 5px solid green;
}
<button>Click or Tab me!</button>
<script src="https://cdn.jsdelivr.net/ally.js/1.4.1/ally.min.js"></script>
:focus-within
优雅解决方案的圣杯。 :focus-visible
基本上是 :focus
的纯键盘版本,并且已经在 most modern browsers(以前的 :focus-ring
)上慢慢推出。优点:CSS 解决方案,性能简单,易于实施。
缺点:浏览器支持更好,但在 Safari 尚未加入的情况下仍然不理想。
button {
width: 180px;
height: 60px;
background: #999;
border: none;
outline: none;
}
button:focus-visible {
outline: 5px solid green;
}
<button>Click or Tab me!</button>
tabindex="-1"
hack 表明我们可以通过在 span
元素(技术上有效的 HTML)中添加 button
然后赋予该跨度 {{1 }} 和不同的焦点样式。优点:不涉及 JS,似乎适用于所有浏览器。
缺点:需要网站上所有按钮和链接内的垃圾邮件跨度,需要将填充从按钮/链接移动到内部跨度,需要调整各种跟踪标签,例如 gtm。
tabindex="-1"
button {
width: 180px;
height: 60px;
background: #999;
border: none;
outline: none;
}
button > span {
display: flex;
justify-content: center;
height: 100%;
align-items: center;
}
button:focus {
outline: 0;
}
button:focus > span {
outline: 5px solid green;
}
[tabindex="-1"]:focus {
outline: none !important;
}
现在的问题是,是否有更好或更简单的方法来实现此功能?是否有我缺少的行业标准?
答案 0 :(得分:2)
简短回答:不,如果您的目标是“完美”(它在所有浏览器中的工作方式完全相同),您基本上已经在此处列出了您的选项。
然而,正如您所说,所有 4 个选项都有缺点。
就我个人而言,我会选择“最适合”的解决方案,在这种情况下,某些用户可能会在点击时获得焦点指示器,但大多数新浏览器都会妥善处理:
button:focus {
outline: 3px solid #333;
outline-offset: 3px;
}
button:focus:not(:focus-visible) {
outline: none;
outline-offset: 0;
}
<button>A test</button>
<button>Another test</button>
Safari 仍会在点击时显示焦点指示器..... 没关系!
Safari 最终会赶上并使用 :focus-visible
。在那之前,上面的方法是确保支持 :focus-visible
的浏览器按预期运行而不支持它的浏览器回退到在点击时提供焦点指示器的最简单方法。
然后我会使用一个基于支持条件加载的 polyfill。
This answer details how to detect support for :focus-visible
此时您可以有条件地加载 a :focus-visible
polyfill(3.5kb gzipped)。
我个人不喜欢这个解决方案,因为你必须改变你所有的 CSS....但我并不像大多数人那样被点击时显示的焦点指示器所困扰,所以我可能会有偏见!
答案 1 :(得分:1)
我一时想不起来了,但是有一种使用 JS 的方法,基本上是通过鼠标单击来删除轮廓。我是一年前做的,我只是对细节一头雾水。