views:

568

answers:

3

I'm having an issue where I'm trying to update the background gradient of an element with JavaScript based on values I specify.

I tried this route:

elem.style.backgroundImage = '-webkit-gradient(radial, '+x+' '+y+', 0, '+x+' '+y+', 800, from(#ccc), to(#333)), -moz-radial-gradient('+x+'px '+y+'px, circle cover, #ccc 0, #333 100%)';

Since Webkit and Gecko have two different syntaxes for CSS3 gradients, I need to specify both. However, the above code doesn't work. It works if I only have just the Gecko syntax or just the Webkit syntax, not both.

I think you can check for CSS gradient support, but my question is, is there a way to check which syntax needs to be used without browser sniffing? Keep in mind that I need to set my gradients this way since the x and y coordinates of the gradient change dynamically.

Hope this makes sense, thanks.

+1  A: 

Edit The below is useful for other reasons, but in fact, I don't think it helps with the OP's problem of knowing whether to use the WebKit or Firefox symtax! (Doh) It helps with knowing whether the gradients can be used at all.

Edit again But! Looking at the Modernizr source shows us how to do it with a feature test (they're clever, those folks). You can probably figure it out by looking at the source yourself, but here's a quickly hacked-together example:

function testGradientSyntax() {
    var element;

    element = document.createElement("testsyntax");
    element.style.cssText =
        "background: -webkit-gradient(radial, 45 45, 10, 52 50, 30, from(#A7D30C), to(rgba(1,159,98,0)), color-stop(90%, #019F62))";
    if (element.style.background.indexOf("-webkit") >= 0) {
        // It's WebKit syntax
        log("This supports WebKit syntax");
    }
    else {
        // It's not WebKit syntax
        log("This doesn't support WebKit syntax");
    }
}

You might want to use Modernizr for this. It detects the relevant syntax and provides a way for you to use a single CSS file with both syntaxes.

Sample gradient code from the docs:

button.glossy {
   background: #ccc url(gloss.png) 50% 50% repeat-x;
}
.cssgradients button.glossy {
   background: #ccc -webkit-gradient(linear, left top, left bottom, 
         from(rgba(255,255,255, .4)), 
         color-stop(0.5, rgba(255,255,255, .7)), 
         color-stop(0.5, rgba(0,0,0, .2)), 
         to(rgba(0,0,0, .1)));
}
.cssgradients button.glossy:hover {
   background-color: #fff;
}

(Edit In the above, I've removed a line from the end of the .cssgradients button.glossy rule that looked to me like an error in the docs.)

See that .cssgradients class? When you run Modernizr, it detects whether that's the relevant syntax and if so adds the class to your html element, which turns on the descendant selector .cssgradients button.glossy so that rule gets applied.

This is, sadly, all dependent on the browser having Javascript enabled.

T.J. Crowder
Thanks T.J., Modernizer was the ticket. It didn't do exactly what I needed to accomplish but it pushed me in the right direction to get what I needed.
Scott Christopherson
@Scott Christopherson: Good deal, glad that helped. I think you must have been looking at Modernizr at the same time I was looking through the source to see how they did the test, so my update may be too late, but I've added an update showing a feature test for WebKit syntax. Same concept can be applied to `-moz`, etc.
T.J. Crowder
Haha yeah not long after you posted Modernizer I went and crawled through its source to find the gradient section.
Scott Christopherson
+1  A: 

If anyone's interested, here's what I came up with. I'm sure it could use a lot of improvement, but it works so far.

var syntax;
var syntaxCheck = document.createElement('syntax');
var syntaxFound = false;
while(!syntaxFound) {

     syntaxCheck.style.backgroundImage = '-webkit-gradient(linear,left top,right bottom,from(#9f9),to(white))';
     if(syntaxCheck.style.backgroundImage.indexOf( 'webkit' ) !== -1) {
          syntax = 'webkit';
          syntaxFound = true;
          break;
     }

     syntaxCheck.style.backgroundImage = '-moz-linear-gradient(left top,#9f9, white)';
     if(syntaxCheck.style.backgroundImage.indexOf( 'moz' ) !== -1) {
          syntax = 'moz';
          syntaxFound = true;
          break;
     }
}

if(syntax == 'webkit') // use -webkit syntax
else if(syntax == 'moz') // use -moz syntax
Scott Christopherson
LOL! Great minds, I think we were both doing this at the same time. :-)
T.J. Crowder
Hahaha nice!! Thanks for the help T.J.
Scott Christopherson
+3  A: 

You shouldn't need to do any detection at all. Just set element.style.backgroundImage twice in succession, and the ones that don't parse will get ignored.

David Baron
Ah, that's true. I thought doing that would cause problems but I just tried it and it still works. Well my current situation no longer needs to detect the correct syntax, but if anyone ever does in the future, they can look here.
Scott Christopherson