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 Answers 2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

+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))";
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).

2 Comments

Thanks! I still don't understand what's going on in the setCss function there though. Why is .split(' ') being used on -webkit- ?
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)