I would like to add, that based on the Spec,其中包含: focus-visible 伪类, browsers should now only 表示注意力集中 when it is helpful to the user - such as in cases where the user interacts with the page via a keyboard or some other non-pointing device
Browsers that don’t support :focus-visible use the focus styles
defined in the :focus rule and ignore the second style rule completely
(因为: focus ——可见对他们来说是未知的)。
This excellent article by Roman Komarov poses a viable solution for achieving 只使用键盘的焦点样式 for 纽扣, 链接 and other container elements such as 跨度 or Div (which are artificially made focusable with the tabindex attribute)
解决方案:
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;
}
/* Fixing the Safari bug for `<button>`s overflow */
.btn__content {
position: relative;
}
/* All the states on the inner element */
.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;
}
/* Removing default outline only after we've added our custom one */
.btn:focus,
.btn__content:focus {
outline: none;
}
<h2>Keyboard-only focus styles</h2>
<button id="btn" class="btn" type="button">
<span class="btn__content" tabindex="-1">
I'm a button!
</span>
</button>
<a class="btn" href="#x">
<span class="btn__content" tabindex="-1">
I'm a link!
</span>
</a>
<span class="btn" tabindex="0">
<span class="btn__content" 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>
Note that 在给定的时间只能聚焦1个 DOM 元素 (and document.activeElement returns this element) - so 只有 the inner element will be focused.
On the other hand: when we tab using the keyboard - only the outer element will get the focus (remember: the inner element has tabindex="-1" and isn't reachable via sequential keyboard navigation) [Note that for inherently non-focusable outer elements like a clickable <div> - we have to artificially make them focusable by adding tabindex="0"]
<h2>Remove css :focus outline only on :hover and :active states</h2>
<button class="btn" type="button">I'm a button!</button>
<a class="btn" href="#x">I'm a link!</a>
<span class="btn" 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>
// Let the document know when the mouse is being used
document.body.addEventListener('mousedown', function() {
document.body.classList.add('using-mouse');
});
// Re-enable focus styling when Tab is pressed
document.body.addEventListener('keydown', function(event) {
if (event.keyCode === 9) {
document.body.classList.remove('using-mouse');
}
});
// Alternatively, re-enable focus styling when any key is pressed
//document.body.addEventListener('keydown', function() {
// document.body.classList.remove('using-mouse');
//});
/* The default outline styling, for greatest accessibility. */
/* You can skip this to just use the browser's defaults. */
:focus {
outline: #08f auto 2px;
}
/* When mouse is detected, ALL focused elements have outline removed. */
body.using-mouse :focus {
outline: none;
}
As several has stated, :focus-visible is the way to go in terms of a pure CSS solution. I want to provide the easiest way I've solved this styling issue using CSS only, however it has some drawbacks in browser support and is not useful for everyone:
@supports not selector(:focus-visible) {
:focus {
// Fallback styles for browsers that doesn't support :focus-visible.
}
}
:focus-visible {
// Tab focus styles
}