3

I'm trying to make my app cross-browser by providing two styles, one for browsers that support CSS 3d animation, and one for the browsers that don't, using this code to feature-detect:

// Function from: https://stackoverflow.com/a/36191841/7982963
const isValueSupported = (prop, value) => {
  const el = document.createElement('div');
  el.style[prop] = value;
  return el.style[prop] === value;
}
// [unction from: http://lea.verou.me/2009/02/check-if-a-css-property-is-supported/
const isPropertySupported = property =>  property in document.body.style;

// Detection style inspired by Modernizr library
if (isValueSupported('perspective', '400px') && isValueSupported('transform-style', 'preserve-3d') && isValueSupported('backface-visibility', 'hidden') && isValueSupported('transform', 'rotateY(-180deg)') && isPropertySupported('perspective') && isPropertySupported('transform-style') && isPropertySupported('backface-visibility') && isPropertySupported('transform') && (!navigator.userAgent.includes('Firefox'))) {
  document.documentElement.classList.add('csstransforms3d');
} else {
  document.documentElement.classList.add('no-csstransforms3d');
}

The problem is that, although some browsers, like Firefox, pass the test, they have some known bugs like Mozilla's backface-visibility bug, so I had to browser-sniff :(.
I quickly found useful results for Firefox: if (navigator.userAgent.includes('Firefox')), but for another browser it happens that I have on my computer called "Baidu browser", I couldn't find any results.
So how to detect these kinds of browsers?

Moaaz Bhnas
  • 1,010
  • 7
  • 18
  • 36
  • Have you tried using Modernizr for feature detection? Note older browser likely don't support `const` and defintiely not arrow functions – charlietfl Nov 20 '18 at 07:52
  • 2
    *Not directly related:* Beware the answer you picked your cssPropertySupported function from was trying to detect if the browser supports a particular css unit. This test will fail for a browser that don't support the property at all. *More related:* It might be cleaner to find a way to reproduce what you are doing in a cross-browser way, rather than trying to find out all the ones that have quirks doing it in your current way => sounds like an X-Y problem to me. – Kaiido Nov 20 '18 at 07:53
  • For instance if what you are trying to do is to make [this fiddle](https://fiddle.jshell.net/bfzcd7ka/2/show/) work the same in all browsers that do support 3D-transforms, simply add a `transform: translate(0);` on the front element: https://jsfiddle.net/0nfbdrq1/show – Kaiido Nov 20 '18 at 07:59
  • @charlietfl Yes, I tried their 'csstransforms3d' and it didn't exclude them. – Moaaz Bhnas Nov 20 '18 at 07:59
  • @Kaiido Thank you very much for the important information. It's safer to stick to the cross-browser compatible solution like you said, but there's gotta be a way to use new CSS features without giving old browsers users bad experience. – Moaaz Bhnas Nov 20 '18 at 08:08
  • I can't take a look on Baidu, but wouldn't it have the same problems as Chromium/Chrome, as it is based on those? – t.niese Nov 20 '18 at 12:49
  • @t.niese I have no idea :'D – Moaaz Bhnas Nov 20 '18 at 15:35
  • 1
    @MoaazBhnas I mean do you encounter a problem if you treat Baidu like Chrome? Most of the unpopular browser are either Chromium, Firefox or WebKit spin-off and with and behave in terms of the rendering like their original. You you more likely want to detect the engine and its version and not the browser. – t.niese Nov 20 '18 at 16:31
  • @t.niese Yeah, when I searched about it, I knew that it was based on chrome, but the bug doesn't happen in chrome. – Moaaz Bhnas Nov 20 '18 at 17:32

1 Answers1

2

You can detect popular browsers in JavaScript with the following code.

// Mobile Browsers
export const isMobile = () => {
  const ua = (navigator || {}).userAgent;
  if (ua) {
    return (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobile|mobile|CriOS/i.test(ua))
  }
  return false;
}

// Opera 8.0+
export const isOpera = () => {
  let opr = window.opr || {};
  return (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
}

// Firefox 1.0+
export const isFirefox = () => typeof InstallTrigger !== 'undefined';

// Safari 3.0+ "[object HTMLElementConstructor]" 
export const isSafari = () => {
  let safari = window.safari || {};
  return /constructor/i.test(window.HTMLElement) || (function (p) { return p.toString() === "[object SafariRemoteNotification]"; })(!window['safari'] || (typeof safari !== 'undefined' && safari.pushNotification));
}

// Internet Explorer 6-11
export const isIE = () => /*@cc_on!@*/false || !!document.documentMode;

// Edge 20+
export const isEdge = () => !isIE() && !!window.StyleMedia;

// Chrome 1+
export const isChrome = () => !!window.chrome && !!window.chrome.loadTimes;

So anything that doesn't match any of these popular browsers, will be an unpopular browser.

Dinesh Pandiyan
  • 5,814
  • 2
  • 30
  • 49