javascripthtmlcssclient-sidevendor-prefix

How to set vendor prefixed CSS values (NOT property names) | client-side


<edit> I actually guessed this would happen but just some seconds after posting I got a flag for "possible duplicate" which is not appropriate! This question is about CSS values and NOT about CSS property names and so it's not a dup of this or this question!!! Its also not a dup of this one because I'm asking for a generic solution.
If you are still not convinced or unsure about what this post is not about, maybe you take a look at the bottom of this question: "What I'm NOT Looking For" and "Who Is NOT Getting The Job Done" </edit>

Is there a way to set an appropriate vendor-prefixed CSS value client-side via JavaScript if needed?

What I'm Looking For

for example: background: -prefix-linear-gradient{...}

I would love to get a generic solution on how to set vendor-prefixed CSS values client-side via JavaScript. Besides this the question is about how to do this client-side and not as a part of the build process (eg POSTcss).

But I also appreciate any hints on


As you can see I already gave an answer on my own. But I'm still looking for better solutions as Autoprefixer comes along with a heavy payload of about 626 KB!


Use Case Scenario

/*
Unprefixed version of "linear-gradient" will only work for
browsers: IE10+, FF16+, Chrome26+, Opera12+, Safari7+.
So how to generate a prefixed version on the fly if necessary?
*/

var aVal = ['linear-gradient(to bottom, #fefefe 0%,#aaaaaa 100%)', 'linear-gradient(to bottom, #aaaaaa 0%,#fefefe 100%']
    style = document.getElementsByTagName('BODY')[0].style,
    i = 0;
(function toggle () {

  if ( i++ ) { i = 0; }
  style.background = aVal[ i ];
  /* here we need something like:
  style.background = parseForPrefix( aVal[ i ] );
  */
  setTimeout(toggle, 2000)

})();
* {
  height: 100%;
  margin: 0;
  padding: 0;
  width: 100%;
}
Unprefixed version of "linear-gradient" will only work for<br>
browsers: IE10+, FF16+, Chrome26+, Opera12+, Safari7+.<br>
So how to generate a prefixed version on the fly if nessecary?

Or imagine something like

jQuery('head').append('<style>body{background:linear-gradient(...)}</style>')

which should be something like

jQuery('head').append('<style>'
    + parseForPrefix('body{background:linear-gradient(...)}') +
'</style>')

instead.


What I'm NOT Looking For

for example: -prefix-transform: translate{...}

The topic how to use vendor prefixes on CSS property names is discussed enough (and not what I'm after).
NOTE: I'm also totally aware of pre-&post-processors used as part of the build process. My whole CSS workflow is based on "Grunt : SASS : PostCSS : Autoprefixer" so no need to give any suggestions on that!


Who Is NOT Getting The Job Done


Solution

  • maybe Modernizr can fix this, like

    // returns: -webkit-linear-gradient(left, red, red)
    Modernizr.prefixedCSSValue('background', 'linear-gradient(left, red, red)')
    

    How it works:

    // prefixedCSSValue is a way test for prefixed css properties (e.g. display: -webkit-flex)
    // @credits modernizr v3.6.0 | Build https://modernizr.com/download?-prefixedcssvalue-dontmin
    Modernizr.prototype.prefixedCSSValue = function(prop, value) {
        var result = false;
        var elem = createElement('div'); // basically: document.createElement.apply(document, ['div'])
        var style = elem.style;
    
        if (prop in style) {
            var i = domPrefixes.length; // domPrefixes === [ "moz", "o", "ms", "webkit" ] or []
    
            style[prop] = value;
            result = style[prop];
    
            while (i-- && !result) {
                style[prop] = '-' + domPrefixes[i] + '-' + value;
                result = style[prop];
            }
        }
    
        if (result === '') {
            result = false;
        }
    
        return result;
    };