11

I'm looking for a solution how we can detect the support of css flex-box and flex-wrap by JavaScript.

I'm aware of modernizr which can do the job but my client does not allow us to load any scripts inside the head section, unfortunately this does not work when loading in the footer.

What is a proper way to achieve this detection on all kind of browsers / devices?

Arek van Schaijk
  • 1,367
  • 10
  • 33

2 Answers2

18

how we can detect the support of css flex-box and flex-wrap by JavaScript.

Create an element and check the style property. If it is supported, it will return nothing i.e. '' else it will return undefined.

For example, if you run the below snippet in Chrome you will get undefined for columns and '' for flex-wrap.

Snippet:

console.log('flex = ' + document.createElement("p").style.flex);
console.log('columns = ' + document.createElement("p").style.columns);
console.log('flex-wrap = ' + document.createElement("p").style.flexWrap);

Although you have mentioned only Javascript in your question, but there is a CSS way of feature detection as well.

The @supports rule, also called CSS Feature Queries.

You provide the CSS declaration as the condition and the browser will execute that to return whether it supports or not. For example, the following CSS will apply green background color if flex is supported.

@supports (display: flex) {
  div { background-color: #0f0; }
}

The browser support is good amongst all modern browsers, barring IE (as usual). For IE and (Safari < 9), you will need to keep a fallback option when @supports rule fails.


Combining the above two, there is an API around that as well which you can use in Javascript to do feature detection.

var isColumnSupported = CSS.supports('columns', '');
console.log('columns supported: ' + isColumnSupported);

var isFlexWrapSupported = CSS.supports('flex-wrap', 'wrap');
console.log('flex-wrap supported: ' + isFlexWrapSupported);
Abhitalks
  • 25,725
  • 4
  • 53
  • 74
0

Since CSS.supports() is not supported on IE

This robust method can test any property:value support:

var cssPropertySupported = (function(){
  var mem = {}; // save test results for efficient future calls with same parameters

  return function cssPropertySupported(prop, values) {
    if( mem[prop+values] )
      return mem[prop+values];

    var element = document.createElement('p'),
        index = values.length,
        name,
        result = false;

    try {
        while (index--) {
          name = values[index];
          element.style.display = name;

          if (element.style.display === name){
            result = true;
            break;
          }
        }
    }
    catch (pError) {}

    mem[prop+values] = result;
    return result;
  }
})();


///////// TEST: ////////////////////
console.log(
cssPropertySupported('display', ['-ms-flexbox', '-webkit-box', 'flex'])
)

You manually need to provide the test function all the possible property names since the code cannot guess (too many possibilities). This keeps the test code slim instead of it have all possible property names already within it.

vsync
  • 87,559
  • 45
  • 247
  • 317