Using JavaScript To Test Browser Support for a CSS Pseudo-Class

February 23, 2021

0

Illustration by my buddy Loor Nicolas


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).

1

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:

2

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} />

// ...


Written by Jon Portella.