7

I use jQuery's .css() method to apply styles to an element. I do this like so:

var cssObj = {
    'background-color' : '#000',
    'background-image': '-webkit-linear-gradient(top,#000,#fff)',
    'background-image': 'linear-gradient(top,#000,#fff)'
};

$(".element").css(cssObj);

The problem with this is that obviously I use duplicate keys in the object, which is not cool.

How can I solve this problem? I need to pass the CSS params with duplicate names to address most browsers.

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
j7nn7k
  • 17,995
  • 19
  • 78
  • 88

5 Answers5

11

Having multiple keys with the same name is not valid, and will generate an error in strict mode.

Create a function/plugin which applies the properties of your cssObj. If a string-string pair is found, set a CSS property with the desired value.
If an array is found, loop through it, and update the property with each value. If an invalid value is found, it's ignored.

DEMO: http://jsfiddle.net/RgfQw/

// Created a plugin for project portability
(function($){
    $.fn.cssMap = function(map){
        var $element = this;
        $.each(map, function(property, value){
            if (value instanceof Array) {
                for(var i=0, len=value.length; i<len; i++) {
                    $element.css(property, value[i]);
                }
            } else {
                $element.css(property, value);
            }
        });
    }
})(jQuery);

// Usage:
var cssObj = {
    'background-color': '#000',
    'background-image': ['-webkit-linear-gradient(top,#000,#fff)',
                         'linear-gradient(top,#000,#fff)']
};
$(".element").cssMap(cssObj);
Rob W
  • 341,306
  • 83
  • 791
  • 678
  • Great answer, nice technique. Added to favourites for later use. – Rory McCrossan Dec 10 '11 at 15:36
  • Tried this out and it works beautifully, except for Safari 5.0 for some reason...? – Owen Hoskins May 03 '12 at 16:52
  • 1
    @Owen I have tested it in Safar 4.0.5, 5.0.1 and 5.1.2. These look fine **: http://i.stack.imgur.com/3A3Gs.png** (screenshot) – Rob W May 03 '12 at 19:44
  • @Rob W, sorry for the late reply, using Multi-Safari 4.0.5 on max osx, the jsfiddle returned this black bar: [screenshot link](http://owenhoskins.com/screenshots/cssmap-safari4.0.5.png) – Owen Hoskins Jun 06 '12 at 17:56
  • 1
    @OwenHoskins That's because the syntax in the answer is only supported in Safari 5.1. In Safari 4-5.0, `-webkit-gradient(linear, left top, left bottom, color-stop(0%,#000), color-stop(100%,#fff))` will do the trick. Prior Safari 4.0, gradients weren't even supported. Here's an updated fiddle which includes gradients for all browsers: http://jsfiddle.net/RgfQw/2/ (with exception of IE9-, for which [filters](http://stackoverflow.com/questions/7546638/css3-cross-browser-linear-gradient/7546655#7546655) have to be used). – Rob W Jun 06 '12 at 19:44
  • @Rob W - Right you are, I wasn't aware of the differences in syntax... thanks for that!! – Owen Hoskins Jun 07 '12 at 12:15
2

My advice would be to put your CSS into your stylesheet in it's own class, and simply add that class to your element instead. The browser itself will determine which of the background-image properties it supports, and will therefore only render that one.

CSS

.gradient-bg {
    background-color: #000;
    background-image: -webkit-linear-gradient(top, #000, #fff);
    background-image: linear-gradient(top, #000, #fff)
}

jQuery

$(".element").addClass("gradient-bg");
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
0

There is a repository of cssHooks on github for most properties. Writing your own hook is tricky, lots of edge cases.

https://github.com/brandonaaron/jquery-cssHooks

For background image gradient, you'd need:

https://github.com/brandonaaron/jquery-cssHooks/blob/master/gradients.js

Aleksandar Totic
  • 2,557
  • 25
  • 27
0

You need to create a custom $.cssHooks (more info) that determines which one is the correct form, by doing various tests --- or you could just use a css class with $.fn.addClass.

Esailija
  • 138,174
  • 23
  • 272
  • 326
-1

It looks like you imply that .css() method works like CSS attributes in a .css file. I don't think it works like that. But here are few alternatives:

  1. Use browser sniffing (why not? you already doing multi-browser CSS with vendor prefixes)

  2. Use actual stylesheet linked as <link /> tag

  3. Create <style> tag and add rules to it, dynamically.

  4. Use style attribute: $('#my').attr('style', 'background: ...; bakground: ...; border-radius: ...; -moz-border-radius: ...;');

alx
  • 2,314
  • 2
  • 18
  • 22
  • From what I read in the jQuery docs it should work. See .css( map ) on http://api.jquery.com/css/ – j7nn7k Dec 10 '11 at 15:21