3

So I need to detect if a user's browser supports CSS gradients, that's it. I would use Modernizr, but even with only including gradient detection, it would be wasteful compared to just doing it myself.

As I understand it, this would be how to go about it;

  1. Creating an element that isn't added to the DOM
  2. Setting background-image to linear-gradient with all the vendor prefixes
  3. Reading background-image and checking for gradient, to see if it's still there

I couldn't figure out Modernizr's source though, what's the core of what they're doing in this? So I can do it myself. http://modernizr.com/download/#-cssgradients-prefixes

2 Answers2

10

Just to add the exact code I used, for reference. Here it is:

var mElem = document.createElement('modern'),
    mStyle = mElem.style;

mStyle.backgroundImage = "linear-gradient(left top, #9f9, white)";
mStyle.backgroundImage = "-o-linear-gradient(left top, #9f9, white)";
mStyle.backgroundImage = "-moz-linear-gradient(left top, #9f9, white)";
mStyle.backgroundImage = "-webkit-linear-gradient(left top, #9f9, white)";
mStyle.backgroundImage = "-ms-linear-gradient(left top, #9f9, white)";
mStyle.backgroundImage = "-webkit-gradient(linear, left top, right bottom, from(#9f9), to(white))";

if (mStyle.backgroundImage.indexOf("gradient") == -1) alert("Gradients are not available. Get a better browser and try again.");

It works exactly the same as Modernizr's implementation, but I've just written out the various gradients by hand, rather than having it automatically done. Wasn't necessary to have it done automatically for such a small feature detect.

  • 1
    +1... a little more elegant way of writing that repeating code: `["","-o-","-moz-","-webkit-","-ms-"].forEach(function(el,i){ mStyle.backgroundImage = el+"linear-gradient(top, #9f9, white)"; }) mStyle.backgroundImage = "-webkit-gradient(linear, top, bottom, from(#9f9), to(white))";` – Phil Tune Apr 24 '14 at 14:39
3

Their test is really basic and you can just extract it:

    function supports_gradients() {
    /**
     * For CSS Gradients syntax, please see:
     * webkit.org/blog/175/introducing-css-gradients/
     * developer.mozilla.org/en/CSS/-moz-linear-gradient
     * developer.mozilla.org/en/CSS/-moz-radial-gradient
     * dev.w3.org/csswg/css3-images/#gradients-
     */

    var str1 = 'background-image:',
        str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));',
        str3 = 'linear-gradient(left top,#9f9, white);';

    setCss(
         // legacy webkit syntax (FIXME: remove when syntax not in use anymore)
          (str1 + '-webkit- '.split(' ').join(str2 + str1)
         // standard syntax             // trailing 'background-image:'
          + prefixes.join(str3 + str1)).slice(0, -str1.length)
    );

    return contains(mStyle.backgroundImage, 'gradient');
};

For this to work you'd also have to extract contains() and setCss() unless you've got your own versions of these methods (say, from jQuery).

Andrew Kolesnikov
  • 1,920
  • 1
  • 14
  • 20
  • Thanks! I still don't understand what's going on in the setCss function there though. Why is `.split(' ')` being used on `-webkit- ` ? –  Jun 01 '12 at 16:10
  • It's a weird way to construct the following `background-image:-webkit-gradient(linear,left top,right bottom,from(#9f9),to(white));background-image:` + prefixes.join(str3 + str1)).slice(0, -str1.length) – Andrew Kolesnikov Jun 01 '12 at 16:23