这种优良制品由罗马科马罗夫构成用于实现可行的解决方案 仅键盘聚焦样式 为 按钮 , 链接
及其它容器元件,例如 跨度 或 div的 (其是人工制造可对焦用的tabindex属性)
解决方案:
button { -moz-appearance: none; -webkit-appearance: none; background: none; border: none; outline: none; font-size: inherit;}.btn { all: initial; margin: 1em; display: inline-block;}.btn__content { background: orange; padding: 1em; cursor: pointer; display: inline-block;}.btn__content { position: relative;}.btn:hover > .btn__content { background: salmon;}.btn:active > .btn__content { background: darkorange;}.btn:focus > .btn__content { box-shadow: 0 0 2px 2px #51a7e8; color: lime;}.btn:focus,.btn__content:focus { outline: none;}<h2>Keyboard-only focus styles</h2><button id="btn" type="button"> <span tabindex="-1"> I'm a button! </span></button><a href="#x"> <span tabindex="-1"> I'm a link! </span></a><span tabindex="0"> <span tabindex="-1"> I'm a span! </span></span><p>Try clicking any of the the 3 focusable elements above - no focus styles will show</p><p>Now try tabbing - behold - focus styles</p>码笔
1)将原始交互元素的内容包装在另一个内部元素中
tabindex="-1"(请参见下面的说明)
因此,与其说:
<button id="btn" type="button">I'm a button!</button>
做这个:
<button id="btn" type="button"> <span tabindex="-1"> I'm a button! </span></button>
2)将CSS样式移至内部元素(布局CSS应保留在原始外部元素上)-这样外部元素的宽度/高度将来自内部元素等。
3)从外部和内部元素中删除默认的焦点样式:
.btn:focus,.btn__content:focus { outline: none;}4) 仅当 外部元素具有焦点 时 , 才 将焦点样式添加回内部元素:
.btn:focus > .btn__content { box-shadow: 0 0 2px 2px #51a7e8; color: lime; }为什么这样做?
这里的技巧是使用
tabindex="-1"- 设置MDN设置内部元素:
负值(通常为tabindex =“-1”表示该元素应可聚焦,但不应通过顺序键盘导航来访问…
因此,该元素 可 通过单击鼠标或以编程方式进行 聚焦 ,但另一方面-无法通过键盘的“选项卡”访问。
因此,当单击交互式元素时, 内部元素 将获得焦点。由于我们已删除焦点样式,因此不会显示。
.btn:focus,.btn__content:focus { outline: none;}请注意, 在给定的时间只能集中1个DOM元素 (并
document.activeElement返回此元素)-因此, 仅
内部元素将被聚焦。
另一方面:当我们使用键盘进行制表时- 只有外部元素会获得焦点 (请记住:内部元素具有tabindex
=“-1”并且无法通过顺序键盘导航访问)[请注意,对于固有的非可聚焦的外部元素(如可点击的元素)
<div>-我们必须通过添加
tabindex="0"]
人为地使其变得可聚焦
现在,我们的CSS开始运行,并向中添加了仅键盘的焦点样式
the inner element。
.btn:focus > .btn__content { box-shadow: 0 0 2px 2px #51a7e8; color: lime; }当然,我们要确保当我们点击并按下时
enter-我们没有破坏我们的交互元素,并且javascript将运行。
这是一个演示,确实是这种情况的演示,请注意,尽管您仅免费获得了固有交互元素(例如按钮和链接)(例如,跨度-您需要手动进行编码:)
//var elem = Array.prototype.slice.call(document.querySelectorAll('.btn'));var btns = document.querySelectorAll('.btn');var fakeBtns = document.querySelectorAll('.btn[tabindex="0"]');var animate = function() { console.log('clicked!');}var kbAnimate = function(e) { console.log('clicking fake btn with keyboard tab + enter...'); var pre = e.which; // 13 = Return, 32 = Space if (pre === 13) { this.click(); }}Array.from(btns).forEach(function(element) { element.addEventListener('click', animate);});Array.from(fakeBtns).forEach(function(element) { element.addEventListener('keydown', kbAnimate);});button { -moz-appearance: none; -webkit-appearance: none; background: none; border: none; outline: none; font-size: inherit;}.btn { all: initial; margin: 1em; display: inline-block;}.btn__content { background: orange; padding: 1em; cursor: pointer; display: inline-block;}.btn__content { position: relative;}.btn:hover > .btn__content { background: salmon;}.btn:active > .btn__content { background: darkorange;}.btn:focus > .btn__content { box-shadow: 0 0 2px 2px #51a7e8; color: lime;}.btn:focus,.btn__content:focus { outline: none;}<h2>Keyboard-only focus styles</h2><button id="btn" type="button"> <span tabindex="-1"> I'm a button! </span></button><a href="#x"> <span tabindex="-1"> I'm a link! </span></a><span tabindex="0"> <span tabindex="-1"> I'm a span! </span></span><p>Try clicking any of the the 3 focusable elements above - no focus styles will show</p><p>Now try tabbing + enter - behold - our interactive elements work</p>码笔
注意:
1)尽管这似乎是一个过于复杂的解决方案,但对于非Javascript解决方案而言,它确实令人印象深刻。简单的纯css的“解决方案”
:hover和
:active伪类样式都根本不起作用。(当然,除非您假设交互元素在单击时像模态提示中的按钮一样立即消失)
button { -moz-appearance: none; -webkit-appearance: none; background: none; border: none; font-size: inherit;}.btn { margin: 1em; display: inline-block; background: orange; padding: 1em; cursor: pointer;}.btn:hover, .btn:active { outline: none;}<h2>Remove css :focus outline only on :hover and :active states</h2><button type="button">I'm a button!</button><a href="#x">I'm a link!</a><span tabindex="0">I'm a span!</span><h3>Problem: Click on an interactive element.As soon as you hover out - you get the focus styling back - because it is still focused (at least regarding the button and focusable span) </h3>码笔
2)此解决方案并不完美:Windows上的Firefox仍将获得单击按钮的焦点样式-
但这似乎是Firefox的错误(请参阅文章)
3)当浏览器实现:focus-ring伪类时-可能有一个更简单的解决方案-对于它的价值,这里有一个polyfill用于
:focus-ring-参见Chris DeMars的本文。
实用的替代仅键盘的焦点样式
因此,实现仅键盘的焦点样式非常困难。一种 更简单 且可能既满足设计师的期望又可以访问的替代方法/解决方法是,将样式设置为焦点,就像悬停样式一样。
码笔
因此,尽管从技术上讲这不是在实现仅键盘样式,但从本质上讲,它消除了对仅键盘样式的需要。



