38

I have some code:

$("#" + this.id).css("border-radius",this.radius + "px");
$("#" + this.id).css("-moz-border-radius",this.radius + "px");
$("#" + this.id).css("-webkit-border-radius",this.radius + "px");

I am trying to improve lines like this by using JSON to apply them (as shown in jQuery's docs) or by removing the vendor prefix versions completely.

Does jQuery's .css() method automatically apply any required vendor prefixes when changing CSS properties on an element?

Yotam Omer
  • 15,310
  • 11
  • 62
  • 65
Jamesking56
  • 3,683
  • 5
  • 30
  • 61
  • Why don't you use style files instead of javascript, simply add class with venodrs, many extensions add to ide such functionality. And its more readable – Suhan Jul 05 '13 at 11:26
  • You should really write those lines of CSS in the reverse order, so that if both versions exist, the standards one overrides the experimental/vendor one. – Paul S. Jul 05 '13 at 11:26
  • 2
    specifically in terms of `border-radius`, you can probably drop the prefixes anyway; it's been standardised for long enough that there's really not many browsers out there in the wild that still need the prefix. See http://caniuse.com/#search=border-radius – Spudley Jul 05 '13 at 11:27
  • 1
    If you don't mind using a library [prefix free](http://leaverou.github.io/prefixfree/) helps. – Patsy Issa Jul 05 '13 at 11:30

3 Answers3

52

As @zeroflagL wrote it appears that since jQuery 1.8.0 .css() does add browser specific prefixes (see this).

In earlier versions this is not done automatically by jQuery's .css(). You will have to do it by yourself or you can use jQuery's .cssHooks() to add vendor prefixes.

Code example from here:

(function($) {
  if ( !$.cssHooks ) {
    throw("jQuery 1.4.3+ is needed for this plugin to work");
    return;
  }

  function styleSupport( prop ) {
    var vendorProp, supportedProp,
        capProp = prop.charAt(0).toUpperCase() + prop.slice(1),
        prefixes = [ "Moz", "Webkit", "O", "ms" ],
        div = document.createElement( "div" );

    if ( prop in div.style ) {
      supportedProp = prop;
    } else {
      for ( var i = 0; i < prefixes.length; i++ ) {
        vendorProp = prefixes[i] + capProp;
        if ( vendorProp in div.style ) {
          supportedProp = vendorProp;
          break;
        }
      }
    }

    div = null;
    $.support[ prop ] = supportedProp
    return supportedProp;
  }

  // check for style support of your property 
  // TODO by user: swap out myCssPropName for css property
  var myCssPropName = styleSupport("myCssPropName");

  // set cssHooks only for browsers that
  // support a vendor-prefixed border radius
  if (myCssPropName && myCssPropName !== 'myCssPropName') {
    $.cssHooks["myCssPropName"] = {
      get: function(elem, computed, extra) {
        // handle getting the CSS property
        return $.css(elem, myCssPropName);
      },
      set: function(elem, value) {
        // handle setting the CSS value
        elem.style[myCssPropName] = value;
      }
    };
  }
})(jQuery);
Yotam Omer
  • 15,310
  • 11
  • 62
  • 65
  • +1 for cssHooks. Is there a repository with the common prefixes? – Karoly Horvath Jul 05 '13 at 11:25
  • I've seen in the examples: `prefixes = [ "Moz", "Webkit", "O", "ms" ]`. added a code example – Yotam Omer Jul 05 '13 at 11:26
  • Thanks, I'll remove the vendor prefix versions with advice from caniuse.com – Jamesking56 Jul 05 '13 at 11:31
  • 1
    I couldn't find anything about this in the docs. do you have some reference? – Yotam Omer Jul 05 '13 at 21:06
  • 2
    @YotamOmer check these links http://james.padolsey.com/jquery/#v=1.10.2&fn=jQuery.css http://james.padolsey.com/jquery/#v=1.10.2&fn=_vendorPropName http://james.padolsey.com/jquery/#v=1.10.2&fn=_cssPrefixes – Fernando Silva Apr 28 '14 at 22:42
  • Note that jQuery does this only for the property name, not for the property value. Using `$('body').css('cursor', 'grab')` will not automatically transform to `.css('cursor', '-webkit-grab')` on Chrome. – jlh Jun 02 '17 at 13:25
11

jQuery DOES add vendor prefixes. It first checks for the presence of the standard property and if it's not found for a vendor prefixed version. From the source:

// return a css property mapped to a potentially vendor prefixed property
function vendorPropName( style, name ) {
    // shortcut for names that are not vendor prefixed
    if ( name in style ) {
      return name;
     }

    // check for vendor prefixed names
    ...

I don't know since which version, but I think 1.8.

a better oliver
  • 26,330
  • 2
  • 58
  • 66
7

This is now confirmed in the official docs: http://api.jquery.com/css/

Setter ( .css( propertyName, value ) )

As of jQuery 1.8, the .css() setter will automatically take care of prefixing the property name. For example, take .css( "user-select", "none" ) in Chrome/Safari will set it as -webkit-user-select, Firefox will use -moz-user-select, and IE10 will use -ms-user-select.

Getter ( .css( propertyName ) )

The .css() method is a convenient way to get a computed style property from the first matched element, especially in light of the different ways browsers access most of those properties (the getComputedStyle() method in standards-based browsers versus the currentStyle and runtimeStyle properties in Internet Explorer prior to version 9) and the different terms browsers use for certain properties. For example, Internet Explorer's DOM implementation refers to the float property as styleFloat, while W3C standards-compliant browsers refer to it as cssFloat. For consistency, you can simply use "float", and jQuery will translate it to the correct value for each browser.

It doesn't explicitly mention vendor prefixes in the getter context but it's easy to test. For example, $element.css('border-radius') on Chrome returns values set as border-radius or -webkit-border-radius and ignores values set as -moz-border-radius.

Just keep in mind that it's inconsistent across browsers for shorthand properties:

Retrieval of shorthand CSS properties (e.g., margin, background, border), although functional with some browsers, is not guaranteed. For example, if you want to retrieve the rendered border-width, use: $( elem ).css( "borderTopWidth" ), $( elem ).css( "borderBottomWidth" ), and so on.

user56reinstatemonica8
  • 32,576
  • 21
  • 101
  • 125