var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,
reliableTrDimensionsVal, reliableMarginLeftVal,
container = document.createElement( "div" ),
div = document.createElement( "div" );
// Finish early in limited (non-browser) environments
// Support: IE <=9 - 11 only
// Style of cloned element affects source element cloned (#8908)
div.style.backgroundClip = "content-box";
div.cloneNode( true ).style.backgroundClip = "";
support.clearCloneStyle = div.style.backgroundClip === "content-box";
jQuery.extend( support, {
boxSizingReliable: function() {
return boxSizingReliableVal;
pixelBoxStyles: function() {
return pixelBoxStylesVal;
pixelPosition: function() {
reliableMarginLeft: function() {
return reliableMarginLeftVal;
scrollboxSize: function() {
// Support: IE 9 - 11+, Edge 15 - 18+
// IE/Edge misreport `getComputedStyle` of table rows with width/height
// set in CSS while `offset*` properties report correct values.
// Behavior in IE 9 is more subtle than in newer versions & it passes
// some versions of this test; make sure not to make it pass there!
reliableTrDimensions: function() {
var table, tr, trChild, trStyle;
if ( reliableTrDimensionsVal == null ) {
table = document.createElement( "table" );
tr = document.createElement( "tr" );
trChild = document.createElement( "div" );
table.style.cssText = "position:absolute;left:-11111px";
trChild.style.height = "9px";
trStyle = window.getComputedStyle( tr );
reliableTrDimensionsVal = parseInt( trStyle.height ) > 3;
documentElement.removeChild( table );
return reliableTrDimensionsVal;
function curCSS( elem, name, computed ) {
var width, minWidth, maxWidth, ret,
// Retrieving style before computed somehow
// fixes an issue with getting wrong values
computed = computed || getStyles( elem );
// getPropertyValue is needed for:
// .css('filter') (IE 9 only, #12537)
// .css('--customProperty) (#3144)
ret = computed.getPropertyValue( name ) || computed[ name ];
if ( ret === "" && !isAttached( elem ) ) {
ret = jQuery.style( elem, name );
// A tribute to the "awesome hack by Dean Edwards"
// Android Browser returns percentage for some values,
// but width seems to be reliably pixels.
// This is against the CSSOM draft spec:
// https://drafts.csswg.org/cssom/#resolved-values
if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {
// Remember the original values
minWidth = style.minWidth;
maxWidth = style.maxWidth;
// Put in the new values to get a computed value out
style.minWidth = style.maxWidth = style.width = ret;
// Revert the changed values
style.minWidth = minWidth;
style.maxWidth = maxWidth;
return ret !== undefined ?
// Support: IE <=9 - 11 only
// IE returns zIndex value as an integer.
function addGetHookIf( conditionFn, hookFn ) {
// Define the hook, we'll check on the first run if it's really needed.
// Hook not needed (or it's not possible to use it due
// to missing dependency), remove it.
// Hook needed; redefine it so that the support test is not executed again.
return ( this.get = hookFn ).apply( this, arguments );
var cssPrefixes = [ "Webkit", "Moz", "ms" ],
emptyStyle = document.createElement( "div" ).style,
// Return a vendor-prefixed property or undefined
function vendorPropName( name ) {
// Check for vendor prefixed names
var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
name = cssPrefixes[ i ] + capName;
if ( name in emptyStyle ) {
// Return a potentially-mapped jQuery.cssProps or vendor prefixed property
function finalPropName( name ) {
var final = jQuery.cssProps[ name ] || vendorProps[ name ];
if ( name in emptyStyle ) {
return vendorProps[ name ] = vendorPropName( name ) || name;
// Swappable if display is none or starts with table
// except "table", "table-cell", or "table-caption"
// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
rdisplayswap = /^(none|table(?!-c[ea]).+)/,
cssShow = { position: "absolute", visibility: "hidden", display: "block" },
function setPositiveNumber( _elem, value, subtract ) {
// Any relative (+/-) values have already been
// normalized at this point
var matches = rcssNum.exec( value );
// Guard against undefined "subtract", e.g., when used as in cssHooks
Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {
var i = dimension === "width" ? 1 : 0,
// Adjustment may not be necessary
if ( box === ( isBorderBox ? "border" : "content" ) ) {
for ( ; i < 4; i += 2 ) {
// Both box models exclude margin
if ( box === "margin" ) {
delta += jQuery.css( elem, box + cssExpand[ i ], true, styles );
// If we get here with a content-box, we're seeking "padding" or "border" or "margin"
delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
// For "border" or "margin", add border
if ( box !== "padding" ) {
delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
// But still keep track of it otherwise
extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
// If we get here with a border-box (content + padding + border), we're seeking "content" or
// For "content", subtract padding
if ( box === "content" ) {
delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
// For "content" or "padding", subtract border
if ( box !== "margin" ) {
delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
// Account for positive content-box scroll gutter when requested by providing computedVal
if ( !isBorderBox && computedVal >= 0 ) {
// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
// Assuming integer scroll gutter, subtract the rest and round down
delta += Math.max( 0, Math.ceil(
elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
// If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter
// Use an explicit zero to avoid NaN (gh-3964)
function getWidthOrHeight( elem, dimension, extra ) {
// Start with computed style
var styles = getStyles( elem ),
// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).
// Fake content-box until we know it's needed to know the true value.
boxSizingNeeded = !support.boxSizingReliable() || extra,
isBorderBox = boxSizingNeeded &&
jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
valueIsBorderBox = isBorderBox,
val = curCSS( elem, dimension, styles ),
offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );
// Return a confounding non-pixel value or feign ignorance, as appropriate.
if ( rnumnonpx.test( val ) ) {
// Support: IE 9 - 11 only
// Use offsetWidth/offsetHeight for when box sizing is unreliable.
// In those cases, the computed value can be trusted to be border-box.
if ( ( !support.boxSizingReliable() && isBorderBox ||
// Support: IE 10 - 11+, Edge 15 - 18+
// IE/Edge misreport `getComputedStyle` of table rows with width/height
// set in CSS while `offset*` properties report correct values.
// Interestingly, in some cases IE 9 doesn't suffer from this issue.
!support.reliableTrDimensions() && nodeName( elem, "tr" ) ||
// Fall back to offsetWidth/offsetHeight when value is "auto"
// This happens for inline elements with no explicit setting (gh-3571)
// Support: Android <=4.1 - 4.3 only
// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)
!parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) &&
// Make sure the element is visible & connected
elem.getClientRects().length ) {
isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
// Where available, offsetWidth/offsetHeight approximate border box dimensions.
// Where not available (e.g., SVG), assume unreliable box-sizing and interpret the
// retrieved value as a content box dimension.
valueIsBorderBox = offsetProp in elem;
if ( valueIsBorderBox ) {
val = elem[ offsetProp ];
val = parseFloat( val ) || 0;
// Adjust for the element's box model
extra || ( isBorderBox ? "border" : "content" ),
// Provide the current computed size to request scroll gutter calculation (gh-3589)
// Add in style property hooks for overriding the default
// behavior of getting and setting a style property
get: function( elem, computed ) {
// We should always get a number back from opacity
var ret = curCSS( elem, "opacity" );
return ret === "" ? "1" : ret;
// Don't automatically add "px" to these possibly-unitless properties
"animationIterationCount": true,
// Add in properties whose names you wish to fix before
// setting or getting the value
// Get and set the style property on a DOM Node
style: function( elem, name, value, extra ) {
// Don't set styles on text and comment nodes
if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
// Make sure that we're working with the right name
origName = camelCase( name ),
isCustomProp = rcustomProp.test( name ),
// Make sure that we're working with the right name. We don't
// want to query the value if it is a CSS custom property
// since they are user-defined.
name = finalPropName( origName );
// Gets hook for the prefixed version, then unprefixed version
hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
// Check if we're setting a value
if ( value !== undefined ) {
// Convert "+=" or "-=" to relative numbers (#7345)
if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
value = adjustCSS( elem, name, ret );
// Make sure that null and NaN values aren't set (#7116)
if ( value == null || value !== value ) {
// If a number was passed in, add the unit (except for certain CSS properties)
// The isCustomProp check can be removed in jQuery 4.0 when we only auto-append
// "px" to a few hardcoded values.
if ( type === "number" && !isCustomProp ) {
value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
// background-* props affect original clone's values
if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
style[ name ] = "inherit";
// If a hook was provided, use that value, otherwise just set the specified value
if ( !hooks || !( "set" in hooks ) ||
( value = hooks.set( elem, value, extra ) ) !== undefined ) {
style.setProperty( name, value );
// If a hook was provided get the non-computed value from there
if ( hooks && "get" in hooks &&
( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
// Otherwise just get the value from the style object
css: function( elem, name, extra, styles ) {
origName = camelCase( name ),
isCustomProp = rcustomProp.test( name );
// Make sure that we're working with the right name. We don't
// want to modify the value if it is a CSS custom property
// since they are user-defined.
name = finalPropName( origName );
// Try prefixed name followed by the unprefixed name
hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
// If a hook was provided get the computed value from there
if ( hooks && "get" in hooks ) {
val = hooks.get( elem, true, extra );
// Otherwise, if a way to get the computed value exists, use that
if ( val === undefined ) {
val = curCSS( elem, name, styles );
// Convert "normal" to computed value
if ( val === "normal" && name in cssNormalTransform ) {
val = cssNormalTransform[ name ];
// Make numeric if forced or a qualifier was provided and val looks numeric
if ( extra === "" || extra ) {