3 var ralpha = /alpha\([^)]*\)/i,
4 ropacity = /opacity=([^)]*)/,
5 // fixed for IE9, see #8346
6 rupper = /([A-Z]|^ms)/g,
7 rnum = /^[\-+]?(?:\d*\.)?\d+$/i,
8 rnumnonpx = /^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i,
9 rrelNum = /^([\-+])=([\-+.\de]+)/,
12 cssShow = { position: "absolute", visibility: "hidden", display: "block" },
14 // order is important!
15 cssExpand = [ "Top", "Right", "Bottom", "Left" ],
22 jQuery.fn.css = function( name, value ) {
23 return jQuery.access( this, function( elem, name, value ) {
24 return value !== undefined ?
25 jQuery.style( elem, name, value ) :
26 jQuery.css( elem, name );
27 }, name, value, arguments.length > 1 );
31 // Add in style property hooks for overriding the default
32 // behavior of getting and setting a style property
35 get: function( elem, computed ) {
37 // We should always get a number back from opacity
38 var ret = curCSS( elem, "opacity" );
39 return ret === "" ? "1" : ret;
42 return elem.style.opacity;
48 // Exclude the following css properties to add px
60 // Add in properties whose names you wish to fix before
61 // setting or getting the value
63 // normalize float css property
64 "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
67 // Get and set the style property on a DOM Node
68 style: function( elem, name, value, extra ) {
69 // Don't set styles on text and comment nodes
70 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
74 // Make sure that we're working with the right name
75 var ret, type, origName = jQuery.camelCase( name ),
76 style = elem.style, hooks = jQuery.cssHooks[ origName ];
78 name = jQuery.cssProps[ origName ] || origName;
80 // Check if we're setting a value
81 if ( value !== undefined ) {
84 // convert relative number strings (+= or -=) to relative numbers. #7345
85 if ( type === "string" && (ret = rrelNum.exec( value )) ) {
86 value = ( +( ret[1] + 1) * +ret[2] ) + parseFloat( jQuery.css( elem, name ) );
91 // Make sure that NaN and null values aren't set. See: #7116
92 if ( value == null || type === "number" && isNaN( value ) ) {
96 // If a number was passed in, add 'px' to the (except for certain CSS properties)
97 if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
101 // If a hook was provided, use that value, otherwise just set the specified value
102 if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
103 // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
106 style[ name ] = value;
111 // If a hook was provided get the non-computed value from there
112 if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
116 // Otherwise just get the value from the style object
117 return style[ name ];
121 css: function( elem, name, extra ) {
124 // Make sure that we're working with the right name
125 name = jQuery.camelCase( name );
126 hooks = jQuery.cssHooks[ name ];
127 name = jQuery.cssProps[ name ] || name;
129 // cssFloat needs a special treatment
130 if ( name === "cssFloat" ) {
134 // If a hook was provided get the computed value from there
135 if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
138 // Otherwise, if a way to get the computed value exists, use that
139 } else if ( curCSS ) {
140 return curCSS( elem, name );
144 // A method for quickly swapping in/out CSS properties to get correct calculations
145 swap: function( elem, options, callback ) {
149 // Remember the old values, and insert the new ones
150 for ( name in options ) {
151 old[ name ] = elem.style[ name ];
152 elem.style[ name ] = options[ name ];
155 ret = callback.call( elem );
157 // Revert the old values
158 for ( name in options ) {
159 elem.style[ name ] = old[ name ];
166 // DEPRECATED in 1.3, Use jQuery.css() instead
167 jQuery.curCSS = jQuery.css;
169 if ( document.defaultView && document.defaultView.getComputedStyle ) {
170 getComputedStyle = function( elem, name ) {
171 var ret, defaultView, computedStyle, width,
174 name = name.replace( rupper, "-$1" ).toLowerCase();
176 if ( (defaultView = elem.ownerDocument.defaultView) &&
177 (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
179 ret = computedStyle.getPropertyValue( name );
180 if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
181 ret = jQuery.style( elem, name );
185 // A tribute to the "awesome hack by Dean Edwards"
186 // WebKit uses "computed value (percentage if specified)" instead of "used value" for margins
187 // which is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
188 if ( !jQuery.support.pixelMargin && computedStyle && rmargin.test( name ) && rnumnonpx.test( ret ) ) {
191 ret = computedStyle.width;
199 if ( document.documentElement.currentStyle ) {
200 currentStyle = function( elem, name ) {
201 var left, rsLeft, uncomputed,
202 ret = elem.currentStyle && elem.currentStyle[ name ],
205 // Avoid setting ret to empty string here
206 // so we don't default to auto
207 if ( ret == null && style && (uncomputed = style[ name ]) ) {
211 // From the awesome hack by Dean Edwards
212 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
214 // If we're not dealing with a regular pixel number
215 // but a number that has a weird ending, we need to convert it to pixels
216 if ( rnumnonpx.test( ret ) ) {
218 // Remember the original values
220 rsLeft = elem.runtimeStyle && elem.runtimeStyle.left;
222 // Put in the new values to get a computed value out
224 elem.runtimeStyle.left = elem.currentStyle.left;
226 style.left = name === "fontSize" ? "1em" : ret;
227 ret = style.pixelLeft + "px";
229 // Revert the changed values
232 elem.runtimeStyle.left = rsLeft;
236 return ret === "" ? "auto" : ret;
240 curCSS = getComputedStyle || currentStyle;
242 function getWidthOrHeight( elem, name, extra ) {
244 // Start with offset property
245 var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
246 i = name === "width" ? 1 : 0,
250 if ( extra !== "border" ) {
251 for ( ; i < len; i += 2 ) {
253 val -= parseFloat( jQuery.css( elem, "padding" + cssExpand[ i ] ) ) || 0;
255 if ( extra === "margin" ) {
256 val += parseFloat( jQuery.css( elem, extra + cssExpand[ i ] ) ) || 0;
258 val -= parseFloat( jQuery.css( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
266 // Fall back to computed then uncomputed css if necessary
267 val = curCSS( elem, name );
268 if ( val < 0 || val == null ) {
269 val = elem.style[ name ];
272 // Computed unit is not pixels. Stop here and return.
273 if ( rnumnonpx.test(val) ) {
277 // Normalize "", auto, and prepare for extra
278 val = parseFloat( val ) || 0;
280 // Add padding, border, margin
282 for ( ; i < len; i += 2 ) {
283 val += parseFloat( jQuery.css( elem, "padding" + cssExpand[ i ] ) ) || 0;
284 if ( extra !== "padding" ) {
285 val += parseFloat( jQuery.css( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
287 if ( extra === "margin" ) {
288 val += parseFloat( jQuery.css( elem, extra + cssExpand[ i ]) ) || 0;
296 jQuery.each([ "height", "width" ], function( i, name ) {
297 jQuery.cssHooks[ name ] = {
298 get: function( elem, computed, extra ) {
300 if ( elem.offsetWidth !== 0 ) {
301 return getWidthOrHeight( elem, name, extra );
303 return jQuery.swap( elem, cssShow, function() {
304 return getWidthOrHeight( elem, name, extra );
310 set: function( elem, value ) {
311 return rnum.test( value ) ?
318 if ( !jQuery.support.opacity ) {
319 jQuery.cssHooks.opacity = {
320 get: function( elem, computed ) {
321 // IE uses filters for opacity
322 return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
323 ( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
327 set: function( elem, value ) {
328 var style = elem.style,
329 currentStyle = elem.currentStyle,
330 opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
331 filter = currentStyle && currentStyle.filter || style.filter || "";
333 // IE has trouble with opacity if it does not have layout
334 // Force it by setting the zoom level
337 // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
338 if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" ) {
340 // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
341 // if "filter:" is present at all, clearType is disabled, we want to avoid this
342 // style.removeAttribute is IE Only, but so apparently is this code path...
343 style.removeAttribute( "filter" );
345 // if there there is no filter style applied in a css rule, we are done
346 if ( currentStyle && !currentStyle.filter ) {
351 // otherwise, set new filter values
352 style.filter = ralpha.test( filter ) ?
353 filter.replace( ralpha, opacity ) :
354 filter + " " + opacity;
360 // This hook cannot be added until DOM ready because the support test
361 // for it is not run until after DOM ready
362 if ( !jQuery.support.reliableMarginRight ) {
363 jQuery.cssHooks.marginRight = {
364 get: function( elem, computed ) {
365 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
366 // Work around by temporarily setting element display to inline-block
367 return jQuery.swap( elem, { "display": "inline-block" }, function() {
369 return curCSS( elem, "margin-right" );
371 return elem.style.marginRight;
379 if ( jQuery.expr && jQuery.expr.filters ) {
380 jQuery.expr.filters.hidden = function( elem ) {
381 var width = elem.offsetWidth,
382 height = elem.offsetHeight;
384 return ( width === 0 && height === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");
387 jQuery.expr.filters.visible = function( elem ) {
388 return !jQuery.expr.filters.hidden( elem );
392 // These hooks are used by animate to expand properties
397 }, function( prefix, suffix ) {
399 jQuery.cssHooks[ prefix + suffix ] = {
400 expand: function( value ) {
403 // assumes a single number if not a string
404 parts = typeof value === "string" ? value.split(" ") : [ value ],
407 for ( i = 0; i < 4; i++ ) {
408 expanded[ prefix + cssExpand[ i ] + suffix ] =
409 parts[ i ] || parts[ i - 2 ] || parts[ 0 ];