Using JavaScript To Test Browser Support for a CSS Pseudo-Class
February 23, 2021 • 3 min read
THE PROBLEM
Some browsers have native support for pseudo-elements that others don’t. This is the case, for example, of ::ms-reveal , the little eye that appears to show/hide password input fields in Microsoft browsers (Internet Explorer and Edge).
Edge’s native password reveal feature.
The problem with this native feature is that if your front-end has its own password reveal feature, you could end up with a layout like this one:
Oops! Edge’s native password reveal feature and our own’s.
A SOLUTION
A quick fix would be to just hide the native reveal password:
::-ms-reveal {
display: none;
}
But why are we so quick to discard a native feature? They’re great! In the end, those are the ones that have been developed and tested to work flawlessly by the same team that has built the browser.
A (NATIVE FRIENDLY) SOLUTION
So in this case, a good approach would be to test if the browser has the::ms-reveal feature, and only show our own if it doesn’t.
/**
* Test for pseudo-class support on the current client
* @param {String} pseudoClass - The pseudo-class to test
* @return {Boolean}
*/
export function supportsPseudoClass(pseudoClass) {
// Get the document stylesheet
const ss = document.styleSheets[0];
// Test the pseudo-class by trying to add and remove a rule to the stylesheet
let formattedPseudoClass = pseudoClass;
try {
if (!/^:/.test(formattedPseudoClass)) {
formattedPseudoClass = ":" + formattedPseudoClass;
}
ss.insertRule("html" + formattedPseudoClass + "{}", 0);
ss.deleteRule(0);
return true;
} catch (e) {
return false;
}
}
Now you can just check for ::ms-reveal and roll your own if it doesn’t exist!
// ...
const hasNativePasswordReveal = supportsPseudoClass("::ms-reveal");
const rightSlot = hasNativePasswordReveal ? null : <PasswordReveal />;
return <PasswordInput rightSlot={rightSlot} />;
// ...