【问题标题】:What is the optimal way of achieving keyboard only :focus styling in 2021?什么是仅实现键盘的最佳方式:2021 年的焦点样式?
【发布时间】:2021-07-15 03:52:48
【问题描述】:

长期以来,通过 CSS outline: none; 从按钮等可交互元素中删除轮廓一直是一种常见做法,因为大多数情况下它看起来不合品牌,但它会阻碍可访问性,并使依赖键盘的残障人士更难浏览网站导航。

问题是我还没有找到一种简单的方法来区分鼠标/键盘之间焦点事件的来源,并且单击以及键盘选项卡元素将触发焦点状态。

我知道这个问题一直是hot topic,但大多数来源都有几年的历史了,所以我将展示我发现的关于如何实现仅键盘焦点的主要 4 种方法,每种方法都有自己的优点缺点:

  1. “作弊”方法,Target.com等一些网站的悬停和聚焦样式相同,这种设计选择让他们可以选择根本不需要移除焦点轮廓。

优点:解决问题。

缺点:设计选项有限。

button {
  width: 180px;
  height: 60px;
  background: #999;
  border: none;
}

button:focus,
button:hover { 
  outline: 5px solid green; 
}
<button>Click or Tab me!</button>
  1. JS 解决方案,Apple.com 等网站使用ally.js 为其可交互元素添加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>
  1. :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;
}
&lt;button&gt;Click or Tab me!&lt;/button&gt;
  1. Roman Komarovtabindex="-1" hack 表明,我们可以通过在 button 元素(技术上有效的 HTML)中添加 span 来区分焦点样式,然后给出该跨度 tabindex="-1" 和不同的焦点样式。

优点:不涉及 JS,似乎在所有浏览器中都能正常工作。

缺点:需要在网站上的所有按钮和链接内发送垃圾邮件,需要将填充从按钮/链接移动到内部跨度,需要调整各种跟踪标签,例如 gtm。

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;
}
<button>
  <span tabindex="-1">Click or Tab me!</span>
</button>

现在的问题是,是否有更好或更简单的方法来实现此功能?是否有我缺少的行业标准?

【问题讨论】:

    标签: javascript html css focus accessibility


    【解决方案1】:

    现在的问题是,是否有更好或更简单的方法来实现此功能?是否有我缺少的行业标准?

    简短的回答:不,如果您的目标是“完美”(它在所有浏览器中的工作原理完全相同),您基本上已经在此处列出了您的选项。

    但是,正如您所说,所有 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)。

    我个人不喜欢这种解决方案,因为您必须更改所有 CSS....但我并不像大多数人那样被点击时显示的焦点指示器所困扰,所以我可能会有偏见!

    【讨论】:

      【解决方案2】:

      我不记得了,但是有一种使用JS的方法,基本上是在鼠标单击时删除轮廓。我是一年前做的,我只是对细节一无所知。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-12-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-26
        • 2010-09-17
        相关资源
        最近更新 更多