Polyfill for `:focus-visible`

Overview

Build Status

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.

Details

Polyfill

Installation

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!

Usage

1. Add the script to your page

    ...
    <script src="/node_modules/focus-visible/dist/focus-visible.min.js"></script>
  </body>
</html>

2. Update your CSS

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-js-focus-visible and data-focus-visible-added attributes.

[data-js-focus-visible] :focus:not([data-focus-visible-added]) {
  outline: none;
}

How it works

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

    • NOTE: this means that HTML elements like <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.

Dependencies

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>

Shadow DOM

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);
}

Lazy-loading

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.

Backwards compatibility

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.

Big Thanks

Cross-browser Testing Platform and Open Source <3 Provided by Sauce Labs

Comments
  • When to match :focus-ring:?

    When to match :focus-ring:?

    Currently we model the behaviour of <button>, which (in Chrome) shows a focus ring when it receives focus after a keyboard event, or when a key is pressed while it is focused.

    Another option would be to show a focus ring only when focus is received from a keyboard event. This would be a break from existing behaviour, but may be input into browsers' eventual decision of what behaviour to model.

    opened by alice 43
  • No focus styling when navigating with keyboard from outside the web content

    No focus styling when navigating with keyboard from outside the web content

    Tested on https://wicg.github.io/focus-ring/demo/

    Using safari: when the address bar has the focus, pressing tab moves focus to the first input field but it does not receive focus styling. Pressing alt+tab moves focus to the last input field but it does not receive focus styling.

    Using chrome: when the address bar has the focus, pressing alt+tab moves focus to the last input field but it does not receive focus styling.

    In both cases, if I press shift after navigating, it does add the styling. I assume there's a problem with catching the keyboard events from outside the web content?

    bug 
    opened by erikkroes 36
  • Focus ring does not account for radio buttons

    Focus ring does not account for radio buttons

    I noticed that the focus-ring polyfill only looks for tab key presses, and not arrow input, which is part of the default behavior for radio buttons.

    I've fixed this locally by adding a few lines to the onKeyDown function.

    function onKeyDown(e) {
        if (e.altKey || e.ctrlKey || e.metaKey)
          return;
    
        if (
    	e.keyCode != 9 // tab
    	&& e.keyCode != 37 // left arrow
    	&& e.keyCode != 38 // up arrow
    	&& e.keyCode != 39 // right arrow
    	&& e.keyCode != 40 // down arrow
    	)
          return;
    
        hadKeyboardEvent = true;
      }
    
    opened by johnevanofski 31
  • Fix issue number #33

    Fix issue number #33

    This PR addresses issue #33 by refining the heuristics for when the focus-ring class is applied: if the user navigates to it via Tab or Shift + Tab.

    In addition, this PR also:

    1. Removes use of data-focus-ring-added attribute
    2. Removes the need for use of dom-matches polyfill dependency
    3. Removes the need for setTimeout() when handling the keydown event.
    opened by kloots 28
  • Is DOM ready necessary?

    Is DOM ready necessary?

    The only line that seems to depend on some sort of DOM readiness is:

    document.body.classList.add('js-focus-visible');
    

    Could that be:

    document.documentElement.classList.add('js-focus-visible');
    

    …so this script could be loaded lazily or async?

    opened by jakearchibald 19
  • Exception: A DOM Element reference is required

    Exception: A DOM Element reference is required

    I just put this into production on unsplash.com and noticed that we're getting thousands of client-side exceptions reported due to A DOM Element reference is required. The offending line is here https://github.com/WICG/focus-ring/blob/0e9f086bbc59ca84a2a932e89df0b71bce18b643/dist/focus-ring.js#L25

    I haven't been able to reproduce this locally. Do you have any ideas why this might be happening? Have you seen it before?

    Thanks!

    opened by OliverJAsh 17
  • add support for ShadowDOM WIP

    add support for ShadowDOM WIP

    This PR adds support for using this polyfill in a project that uses shadowDOM. It was specifically tested using Polymer components.

    2 primary changes were required to make this work. First was a bit of code (placed at the beginning of the file) that allows document level focus listeners to listen inside of shadowDOM. I got that code here. To make the blur listener work, I moved the creation of that listener inside the onFocus function.

    The second change was to change the onFocus and onBlur functions to use either the composedPath function or document.activeElement as was described here

    The CSS required for getting it to work is a bit different than described in the original README. Specifically, you need to add this rule to any component that contains a focusable element.

    :focus:not(.focus-visible) {
      outline: 0;
    }
    

    In the context of shadowDOM, the body level .js-focus-visible isn't particularly meaningful.

    opened by codyloyd 16
  • Shadow DOM support

    Shadow DOM support

    Shadow DOM support

    This change enables custom elements to coordinate with the polyfill in order to apply it to discrete scopes of the composed tree (such as their shadow roots). Highlights include:

    • The polyfill is now exported to window as a function that can be invoked on any Document|ShadowRoot
    • The polyfill is automatically, synchronously applied to the top-level document when its script runs, preserving the existing behavior
    • Code that wishes to use the polyfill in a ShadowRoot can apply it as needed
      • Shadow hosts that have the polyfill applied are decorated with a data-js-focus-visible attribute
    • A focus-visible-polyfill-ready event is now dispatched on window to support lazy loading scenarios (see discussion in #193)

    Example usage as a mixin

    In the course of implementing this proposal, I also crafted a mixin to demonstrate how a custom element should coordinate with the polyfill in order to take advantage of :focus-visible-like capabilities.

    I am not proposing to include the mixin in the main project, but it is linked here for future reference:

    https://github.com/cdata/focus-visible/blob/fc33395294dd69ad8af70e822e6176a8893816e2/src/custom-element-mixin.js#L1-L49

    Compared to #112

    There is an older WIP proposal (#112) up for consideration that attempts to add transparent support for arbitrary shadow roots. This approach would ultimately require that focus and blur be observed at every shadow boundary throughout the composed tree in order to work transparently.

    The design in the proposal before you expects a Shadow DOM-using component author to opt-in to the polyfill. This allows the polyfill to be applied to Shadow DOM-using components that need it, while avoiding the cost of observing changes in shadow roots that do not know about or do not want to use the polyfill.

    Examples

    For the purposes of the following examples:

    • :focus elements are styled with purple color and border-color
    • :focus-visible elements receive the default focus ring
    • Elements with shadow roots have delegatesFocus: true configured
    • Custom elements apply the mixin referenced above to coordinate with the polyfill

    This change w/ pointer traversal | This change w/ keyboard traversal -------------------------------- | ---------------------------------- focus-not-visible | focus-visible

    Shadow root styling problem

    Without this change, it is not possible to use the polyfill from within a shadow root. In the following example, you can see that the top-level document elements can be styled to hide the focus ring when focusing with pointer events, but focusable elements inside of a shadow root still display a focus ring:

    Failure to style shadow root-encapsulated elements | ---------------------------------------------------- | focus-not-visible-broken |

    Fixes #193 Fixes #28 Fixes #112

    opened by cdata 12
  • Element focuses with any key

    Element focuses with any key

    Steps to reproduce:

    1. Click any selectable element.
    2. Press any key except 'Tab' Actual result: The element from the first step has a focus-visible class. Expected: The element has not focus-visible.

    Thank you =)

    opened by SuselMan 11
  • Issue #54: Focus ring does not account for radio buttons

    Issue #54: Focus ring does not account for radio buttons

    Per TODO in documentation:

    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.

    Include other types of keyboard input than the tab key that may produce focus navigation.

    opened by majornista 11
  • Meta-question about eslint-plugin-es5 usage

    Meta-question about eslint-plugin-es5 usage

    This package's .eslint.js includes eslint-plugin-es5 in plugins, but never sets up (or "extends") any rules (e.g. "extends": ["plugin:es5/no-es2015"]). Does the plugin do anything without configuring any rules?

    I tried this on a test project and the plugin failed to catch ES2015+ code without rules being configured. Just curious if I'm missing something!

    opened by tinymachine 10
  • Memory leaks when applyFocusVisiblePolyfill is applied then the element is removed

    Memory leaks when applyFocusVisiblePolyfill is applied then the element is removed

    Hello.

    Some web components with shadowDOM use focus-visible polyfill. We apply applyFocusVisiblePolyfill when the component is attached to the DOM connectedCallback(). When the component is removed, applyFocusVisiblePolyfill keep a reference of it preventing it to be garbage collected.

    So each web-component added then removed are kept in memory and it can make a huge memory leak.

    Potential solution: provide a function to unapply to remove all event listener set by applyFocusVisiblePolyfill at disconnectedCallback.

    More info on memory Leaks https://www.youtube.com/watch?v=YDU_3WdfkxA

    opened by ryuran 0
  • Bump jszip from 3.1.5 to 3.10.1

    Bump jszip from 3.1.5 to 3.10.1

    Bumps jszip from 3.1.5 to 3.10.1.

    Changelog

    Sourced from jszip's changelog.

    v3.10.1 2022-08-02

    • Add sponsorship files.
      • If you appreciate the time spent maintaining JSZip then I would really appreciate your sponsorship.
    • Consolidate metadata types and expose OnUpdateCallback #851 and #852
    • use const instead var in example from README.markdown #828
    • Switch manual download link to HTTPS #839

    Internals:

    • Replace jshint with eslint #842
    • Add performance tests #834

    v3.10.0 2022-05-20

    • Change setimmediate dependency to more efficient one. Fixes Stuk/jszip#617 (see #829)
    • Update types of currentFile metadata to include null (see #826)

    v3.9.1 2022-04-06

    • Fix recursive definition of InputFileFormat introduced in 3.9.0.

    v3.9.0 2022-04-04

    • Update types JSZip#loadAsync to accept a promise for data, and remove arguments from new JSZip() (see #752)
    • Update types for compressionOptions to JSZipFileOptions and JSZipGeneratorOptions (see #722)
    • Add types for generateInternalStream (see #774)

    v3.8.0 2022-03-30

    • Santize filenames when files are loaded with loadAsync, to avoid "zip slip" attacks. The original filename is available on each zip entry as unsafeOriginalName. See the documentation. Many thanks to McCaulay Hudson for reporting.

    v3.7.1 2021-08-05

    • Fix build of dist files.
      • Note: this version ensures the changes from 3.7.0 are actually included in the dist files. Thanks to Evan W for reporting.

    v3.7.0 2021-07-23

    • Fix: Use a null prototype object for this.files (see #766)
      • This change might break existing code if it uses prototype methods on the .files property of a zip object, for example zip.files.toString(). This approach is taken to prevent files in the zip overriding object methods that would exist on a normal object.

    v3.6.0 2021-02-09

    • Fix: redirect main to dist on browsers (see #742)
    • Fix duplicate require DataLengthProbe, utils (see #734)
    • Fix small error in read_zip.md (see #703)

    v3.5.0 2020-05-31

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Bump thenify from 3.3.0 to 3.3.1

    Bump thenify from 3.3.0 to 3.3.1

    Bumps thenify from 3.3.0 to 3.3.1.

    Changelog

    Sourced from thenify's changelog.

    3.3.1 / 2020-06-18

    fixes

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Bump moment from 2.22.2 to 2.29.4

    Bump moment from 2.22.2 to 2.29.4

    Bumps moment from 2.22.2 to 2.29.4.

    Changelog

    Sourced from moment's changelog.

    2.29.4

    • Release Jul 6, 2022
      • #6015 [bugfix] Fix ReDoS in preprocessRFC2822 regex

    2.29.3 Full changelog

    • Release Apr 17, 2022
      • #5995 [bugfix] Remove const usage
      • #5990 misc: fix advisory link

    2.29.2 See full changelog

    • Release Apr 3 2022

    Address https://github.com/moment/moment/security/advisories/GHSA-8hfj-j24r-96c4

    2.29.1 See full changelog

    • Release Oct 6, 2020

    Updated deprecation message, bugfix in hi locale

    2.29.0 See full changelog

    • Release Sept 22, 2020

    New locales (es-mx, bn-bd). Minor bugfixes and locale improvements. More tests. Moment is in maintenance mode. Read more at this link: https://momentjs.com/docs/#/-project-status/

    2.28.0 See full changelog

    • Release Sept 13, 2020

    Fix bug where .format() modifies original instance, and locale updates

    2.27.0 See full changelog

    • Release June 18, 2020

    Added Turkmen locale, other locale improvements, slight TypeScript fixes

    2.26.0 See full changelog

    • Release May 19, 2020

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • `:focus-visible` should match when focus is programmatically moved to inside a dialog

    `:focus-visible` should match when focus is programmatically moved to inside a dialog

    Whether <dialog> or [role="dialog], focus should become visible when it is programmatically moved from outside to inside the dialog. i.e. if a user clicks a button that opens a dialog, and now a button is focused-by-default within the dialog per Dialog, that button should show an indicator regardless of whether the dialog was launched by a mouse or keyboard. (Probably not for touch.)

    This seems like a significant usability hole in the current heuristic, which I don't see discussed directly in other issues here.

    opened by craigkovatch 3
  • Applying :focus-visible state after programmatically moving focus only on initial page landing

    Applying :focus-visible state after programmatically moving focus only on initial page landing

    Hi 👋 !

    I created this codepen demo to illustrate the issue I'm seeing (GIF repro'd on Chrome).

    On first loading into the link, if you click Click to focus the next button, notice that we move focus to the next button (Button to be focused) and a :focus-visible state is applied to it. However, if we then click Random button to click and then again click Click to focus the next button then the :focus-visible state isn't applied.

    The :focus-visible doesn't seem to be applying correctly because I added a e.preventDefault() on the mousedown handler on the first button. For our current application, we need to apply this e.preventDefault().

    The behavior seems to be inconsistent with Safari as well where the :focus-visible state is always being applied even after clicking on the third button.

    I was wondering if there was a way for the focus-visible heuristic to account for this? Or if there's a possible workaround while still maintaining the e.preventDefault() on our mousedown handler.

    GIF of demo (Chrome)

    Description of GIF: Load the codepen demo, then click the first button, notice :focus-visible state, then click the third button and reclick the first button and notice no :focus-visible state

    demo

    opened by domkl14 0
Releases(v5.2.0)
  • v5.2.0(Oct 9, 2020)

  • v5.0.0(Jun 13, 2019)

    • Meta keys (command/ctrl, alt/option, windows key) will no longer trigger :focus-visible. You can combine these keys with your keyboard shortcuts to better support multi-modal users (i.e., someone using a mouse but also pressing keyboard shortcuts like ctrl-k).
    • Shadow DOM support has been added!
    • Ensure target.nodename exists in IE11 (fix)
    Source code(tar.gz)
    Source code(zip)
  • v4.0.1(Jan 12, 2018)

    🚧 Breaking Changes 🚧

    Renamed to :focus-visible

    This release renames the :focus-ring polyfill to :focus-visible. This matches the latest version of the CSS draft spec. https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo. Please be sure to update your code and replace any usage of .focus-ring with .focus-visible.

    Source code(tar.gz)
    Source code(zip)
  • v3.0.0(Nov 16, 2017)

    This is a fairly minor release in that it does not radically alter the behavior of the polyfill. However there are a couple breaking changes (detailed below) which required us to bump the major version.

    🚧 Breaking Changes 🚧

    No longer bundling other polyfills

    The :focus-ring polyfill uses the Element.classList API which is not supported in IE 8-9. In accordance with the W3C's new Polyfill guidance, the :focus-ring polyfill no longer bundles other polyfills so the classList polyfill was removed. This avoids loading unnecessary or duplicate polyfills.

    If you need to support these older browsers you should add the classList polyfill to your page before loading the :focus-ring polyfill. Using a service like Polyfill.io will handle feature detecting and loading the necessary polyfills for you:

    <script src="https://cdn.polyfill.io/v2/polyfill.js?features=Element.prototype.classList"></script>
    

    Ignoring the dist/ directory

    Previously we checked in a built version of the :focus-ring polyfill in the dist/ dir. This was to make it easier to link to in our demo and because we weren't entirely sure what was the best process to publish to npm. This ended up causing a lot of annoying PR churn because every change necessitated rebuilding dist/focus-ring.js and committing it. Having dist checked in was also dangerous because our master branch is not guaranteed to be stable.

    To fix this we've redone our demo so it now points at the latest version of the polyfill on unkpg. While we have always encouraged folks to use the polyfill by installing it from npm, we've taken this a step further and removed the dist directory from the repo. We strongly encourage you to only use versions of the polyfill that have been published to npm. This ensures that they've been properly tested and we're confident in releasing them. If you really want to build from source and check that version into your project, be sure you clone a recent tag.

    Other Changes 📌

    • Radio buttons should now properly apply the .focus-ring class when moving focus with the arrow keys.
    • Fixed a nasty bug where the .focus-ring class was not applied if the user tabbed from the URL bar to an interactive element.
    • Tests! So many tests! We've added a full suit of selenium tests to verify that :focus-ring behaves as expected.
    Source code(tar.gz)
    Source code(zip)
  • v2.0.0(Aug 16, 2017)

    This release comes with a couple of important changes.

    #34 Changes the heuristic so it only matches if the user navigates using Tab or Shift + Tab. We decided to make this change after receiving feedback from partners who said the current heuristic of matching any keypress was too aggressive. In particular, if a user uses a keyboard shortcut in an app, suddenly focus rings start appearing.

    #50, #51 A .js-focus-ring class is now added to the body to signal that the polyfill has loaded. This avoids situations where a developer might disable focus styles only to have the polyfill fail to load. The recommended CSS pattern is now:

    .js-focus-ring :focus:not(.focus-ring) {
        outline: 0;
    }
    

    Full changelog

    Source code(tar.gz)
    Source code(zip)
A Vue.js directive helps track visible elements.

vue-visibility-track A Vue.js directive helps track elements's visibility. Installing Using npm: npm install --save vue-visibility-track Using yarn: y

Xiaolin Wu 0 Mar 26, 2021
Detect when an element is becoming visible or hidden on the page.

vue-observe-visibility Detect when an element is becoming visible or hidden on the page. Demo Sponsors Table of contents Installation Usage Example In

Terminalqo 0 Oct 27, 2020
Keep yourself in the zone and focus in the moment.

Zen. is a productivity app that integrates Eisenhower Matrix, Pomodoros, and part of the Get Things Done (GTD) principles in a unique way, to improve your developer routine. The purpose of Zen is to help you staying in the zone.

Jesus Guerrero 18 Oct 30, 2022
Vue component to trap the focus within a DOM element

focus-trap-vue Vue component to trap the focus within a DOM element Installation For Vue 2 npm install focus-trap focus-trap-vue For Vue 3 npm install

Eduardo San Martin Morote 161 Nov 21, 2022
✨ Automagically manage the visibility of :focus states in your app — by recreating the :focus-visible pseudo-selector behaviour.

✨ Automagically manage the visibility of :focus states in your app — by recreating the :focus-visible pseudoselector behaviour. Supports Vue 3.x out of the box ??

Fabian Beer 5 Jan 29, 2022
It is a trap! A lock for a Focus. A11y util for scoping a focus.

vue-focus-lock It is a trap! We got your focus and will not let him out! This is a small, but very useful for: Modal dialogs. You can not leave it wit

Anton Korzunov 132 Jun 15, 2022
Detect when an element is becoming visible or hidden on the page.

vue-observe-visibility Detect when an element is becoming visible or hidden on the page. Demo Sponsors Table of contents Installation Usage Example In

Guillaume Chau 1.6k Nov 15, 2022
Detect when an element is becoming visible or hidden on the page.

vue-observe-visibility Detect when an element is becoming visible or hidden on the page. Demo Sponsors Table of contents Installation Usage Example In

Guillaume Chau 1.6k Nov 15, 2022
A Vue.js component for detecting when components are visible in the viewport via the Vue.js scoped slots api.

vue-scrollview ScrollView is a Vue.js plugin that includes a set of components and methods for facilitating UI interactions tied to scrolling in your

Chris Hurlburt 115 Jun 28, 2022
v-visible directive for VueJS

VueVisible v-visible directive for VueJS (2.x) Demo A jsFiddle live demo: https://jsfiddle.net/fcpc6utm/ About This plugins adds a v-visible directive

Javis V. Pérez 31 May 8, 2021
A Vue.js directive helps track visible elements.

vue-visibility-track A Vue.js directive helps track elements's visibility. Installing Using npm: npm install --save vue-visibility-track Using yarn: y

Xiaolin Wu 0 Mar 26, 2021
Detect when an element is becoming visible or hidden on the page.

vue-observe-visibility Detect when an element is becoming visible or hidden on the page. Demo Sponsors Table of contents Installation Usage Example In

Terminalqo 0 Oct 27, 2020
A reusable focus directive for reusable Vue.js components

vue-focus A reusable focus directive for reusable Vue.js components Overview It can be tricky to manage input focus. You always have to fall back to a

Denis Karabaza 409 Jul 10, 2022
A Vue.js starter kit that lets you focus on more programming and less configuration.

vue-starter A Vue.js starter kit that lets you focus on more programming and less configuration. A full-featured Webpack setup with hot-reload, lint-o

Rohit Rai 54 Sep 26, 2022
The most complete boilerplate for production-ready PWAs. With focus on performance, development speed, and best practices

vuesion The most complete boilerplate for production-ready PWAs. With focus on performance, development speed, and best practices 一个灵活的、可扩展的、自定的,已经准备好

vuesion 2.6k Nov 22, 2022
Keep yourself in the zone and focus in the moment.

Zen. is a productivity app that integrates Eisenhower Matrix, Pomodoros, and part of the Get Things Done (GTD) principles in a unique way, to improve your developer routine. The purpose of Zen is to help you staying in the zone.

Jesus Guerrero 18 Oct 30, 2022
Set focus point on elements

vue-focuspoint-component Set focus point on elements Demo Demo here Install npm install vue-focuspoint-component or yarn add vue-focuspoint-component

null 33 Sep 19, 2022
A modern, fast and productivity driven SQL client with a focus in UX.

Antares SQL Client Antares is an SQL client based on Electron.js and Vue.js that aims to become a useful tool, especially for developers. Our target i

Fabio Di Stasio 858 Nov 20, 2022
PisaAI is a photo repair and retouching tool, that uses AI algorithms to automatically colorize black& white photos, repair old photos, and optimize blurred out-of-focus photos.

PisaAI(披萨智能)在线图片优化 Project setup yarn install Compiles and hot-reloads for development yarn serve Compiles and minifies for production yarn build L

Mark HOU 10 Sep 21, 2022
Vue component to trap the focus within a DOM element

focus-trap-vue Vue component to trap the focus within a DOM element Installation For Vue 2 npm install focus-trap focus-trap-vue For Vue 3 npm install

Eduardo San Martin Morote 161 Nov 21, 2022