Security News
38% of CISOs Fear They’re Not Moving Fast Enough on AI
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
focus-visible
Advanced tools
The focus-visible npm package is a polyfill for the CSS :focus-visible pseudo-class. It helps developers manage focus styles in a way that only applies them when the user is using a keyboard to navigate, avoiding unwanted focus styles when using a mouse or touch input.
Polyfill for :focus-visible
This line of code imports the focus-visible polyfill, which automatically adds the necessary JavaScript to support the :focus-visible pseudo-class in browsers that do not natively support it.
import 'focus-visible';
Customizing focus styles
This CSS rule ensures that focus styles are only applied when the element has the .focus-visible class, which is added by the polyfill when the user is navigating with a keyboard.
.js-focus-visible :focus:not(.focus-visible) { outline: none; }
The what-input package detects the current input method (mouse, keyboard, touch, etc.) and adds corresponding classes to the body element. This allows developers to apply different styles based on the input method. Unlike focus-visible, what-input provides more granular control over input detection but requires more setup for focus management.
The focus-within-polyfill package is a polyfill for the CSS :focus-within pseudo-class, which applies styles to an element if it or any of its descendants have focus. While it serves a different purpose than focus-visible, it is similar in that it helps manage focus styles in browsers that do not support the native pseudo-class.
Based on the proposed CSS
:focus-visible
pseudo-selector,
this prototype adds a focus-visible
class to the focused element,
in situations in which the :focus-visible
pseudo-selector should match.
npm install --save focus-visible
We recommend only using versions of the polyfill that have been published to npm, rather than cloning the repo and using the source directly. This helps ensure the version you're using is stable and thoroughly tested.
If you do want to build from source, make sure you clone the latest tag!
...
<script src="/node_modules/focus-visible/dist/focus-visible.min.js"></script>
</body>
</html>
We suggest that users
selectively disable the default focus style
by selecting for the case when the polyfill is loaded
and .focus-visible
is not applied to the element:
/*
This will hide the focus indicator if the element receives focus via the mouse,
but it will still show up on keyboard focus.
*/
.js-focus-visible :focus:not(.focus-visible) {
outline: none;
}
If there are elements which should always have a focus ring shown,
authors may explicitly add the focus-visible
class.
If explicitly added, it will not be removed on blur
.
Alternatively, if you're using a framework which overwrites your classes (#179),
you can rely on the data-focus-visible-added
attribute.
.js-focus-visible :focus:not([data-focus-visible-added]) {
outline: none;
}
The script uses two heuristics to determine whether the keyboard is being (or will be) used:
a focus
event immediately following a keydown
event where the key pressed was either Tab
,
Shift + Tab
, or an arrow key.
focus moves into an element which requires keyboard interaction, such as a text field
<input type={text|email|password|...}>
or <textarea>
will always match the :focus-visible
selector, regardless of whether they are focused via a keyboard or a mouse.TODO: ideally, we also trigger keyboard modality following a keyboard event which activates an element or causes a mutation; this still needs to be implemented.
If you want to use :focus-visible
with an older browser you'll need to include an additional polyfill for Element.prototype.classList
.
In accordance with the W3C's new polyfill
guidance, the
:focus-visible
polyfill does not bundle other polyfills.
You can use a service like Polyfill.io to download only the polyfills needed by the current browser. Just add the following line to the start of your page:
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=Element.prototype.classList"></script>
It could be very expensive to apply this polyfill automatically to every shadow root that is created in a given document, so the polyfill ignores shadow roots by default. If you are using Shadow DOM in a component, it is possible to apply this polyfill imperatively to the component's shadow root:
// Check for the polyfill:
if (window.applyFocusVisiblePolyfill != null) {
window.applyFocusVisiblePolyfill(myComponent.shadowRoot);
}
When this polyfill is lazy-loaded, and you are applying the polyfill to a shadow root with JavaScript, it is important to know when the polyfill has become available before trying to use it.
In order to act at the right time, you can observe the global
focus-visible-polyfill-ready
event:
window.addEventListener('focus-visible-polyfill-ready',
() => window.applyFocusVisiblePolyfill(myComponent.shadowRoot),
{ once: true });
Important: this event is only intended to support late application of the polyfill in lazy-loading use cases. Do not write code that depends on the event firing, as it is timing dependent and only fired once. If you plan to lazy-load the polyfill, it is recommended that you check for it synchronously (see example above under "Shadow DOM") and listen for the event only if the polyfill isn't available yet.
Until all browsers ship :focus-visible
developers will need to use it defensively to avoid accidentally
removing focus styles in legacy browsers. This is easy to do with the polyfill.
/*
This will hide the focus indicator if the element receives focus via the mouse,
but it will still show up on keyboard focus.
*/
.js-focus-visible :focus:not(.focus-visible) {
outline: none;
}
/*
Optionally: Define a strong focus indicator for keyboard focus.
If you choose to skip this step then the browser's default focus
indicator will be displayed instead.
*/
.js-focus-visible .focus-visible {
…
}
As explained by the Paciello Group, developers who don't use the polyfill can still defensively rely on :focus-visible
using the
following snippet:
/*
Provide basic, default focus styles.
*/
button:focus {
…
}
/*
Remove default focus styles for mouse users ONLY if
:focus-visible is supported on this platform.
*/
button:focus:not(:focus-visible) {
…
}
/*
Optionally: If :focus-visible is supported on this
platform, provide enhanced focus styles for keyboard
focus.
*/
button:focus-visible {
…
}
In the future, when all browsers support :focus-visible
, the
snippets above will be unnecessary. But until that time it's important
to be mindful when you use :focus-visible
and to ensure you always
have a fallback strategy.
Cross-browser Testing Platform and Open Source <3 Provided by Sauce Labs
FAQs
Polyfill for :focus-visible pseudo-selector
The npm package focus-visible receives a total of 172,793 weekly downloads. As such, focus-visible popularity was classified as popular.
We found that focus-visible demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
Research
Security News
Socket researchers uncovered a backdoored typosquat of BoltDB in the Go ecosystem, exploiting Go Module Proxy caching to persist undetected for years.
Security News
Company News
Socket is joining TC54 to help develop standards for software supply chain security, contributing to the evolution of SBOMs, CycloneDX, and Package URL specifications.