Skip to content

Don't enable polyfill if browser supports ":focus-visible" #237

@kutensky

Description

@kutensky

Currently Chrome with experimental flag enabled supports ":focus-visible" polyfill. It would be nice if polyfill could be enabled only if current browser doesn' support ":focus-visible".
To do that, I propose to check pseudo-class support using this method:

supportsPseudo = function (pseudoClass) {
	// Get the document stylesheet
	var ss = document.styleSheets[0];

	// Create a stylesheet if one doesn't exist
	if (!ss) {
		var el = document.createElement('style');
		document.head.appendChild(el);
		ss = document.styleSheets[0];
		document.head.removeChild(el);
	}

	// Test the pseudo-class by trying to style with it
	var testPseudo = function () {
		try {
			if (!(/^:/).test(pseudoClass)) {
				pseudoClass = ':' + pseudoClass;
			}
			ss.insertRule('html' + pseudoClass + '{}', 0);
			ss.deleteRule(0);
			return true;
		} catch(e) {
			return false;
		}
	};

	// Run the test
	return testPseudo();
};

And then in polyfill modify code on the line 306 with:

if (typeof document !== 'undefined' && !supportsPseudo("focus-visible")) {
	// Apply the polyfill to the global document, so that no JavaScript
	// coordination is required to use the polyfill in the top-level document:
	applyFocusVisiblePolyfill(document);
}

After that we will be able to write css rules for both native ":focus-visible" and polyfill version:

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

Activity

emilio

emilio commented on Aug 29, 2020

@emilio

Drive by, but that's a really really expensive way to test for a pseudo-element. try { document.querySelector(":focus-visible"); return true; } catch { return false } should be much faster.

Justineo

Justineo commented on Aug 30, 2020

@Justineo
Contributor

I’m afraid this requires double your style declarations for .focus-visible to make it work with or without the “polyfill” (technically this project isn’t a real polyfill).

kutensky

kutensky commented on Aug 30, 2020

@kutensky
Author

I’m afraid this requires double your style declarations for .focus-visible to make it work with or without the “polyfill” (technically this project isn’t a real polyfill).

Yeap, that will require a double style declaration. But on the other hand, when browsers start to support his feature (Chrome is going to start supporting it from v.86), no js run will be needed. Currently, polyfill does a lot of background work that isn't good for performance.

robdodson

robdodson commented on Oct 9, 2020

@robdodson
Collaborator

Very good points from everyone.

It sounds like if we land this then we should use @emilio's implementation, but also land a note in the README which explains the need to double up your style declarations. We could also add a note that if folks would prefer, they can use the postcss plugin (https://github.com/csstools/postcss-focus-visible) which I think will let them write their CSS using :focus-visible and then it'll do the right thing depending on their browser support matrix. I'm not a post-css expert but I think that's how it works :)

ryuran

ryuran commented on Nov 15, 2022

@ryuran

Related to #244

This condition could help

if (!window.CSS?.supports?.("selector(:focus-visible)")) { 
  // Apply the polyfill
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @robdodson@ryuran@emilio@Justineo@kutensky

      Issue actions

        Don't enable polyfill if browser supports ":focus-visible" · Issue #237 · WICG/focus-visible