From: Mike Sherov Date: Tue, 10 Apr 2012 21:18:00 +0000 (-0400) Subject: Fix 11004. getWH() box-sizing:border-box includes padding and border. X-Git-Tag: 1.8b1~212 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=d7217cc29c24f582198ce2df7db54a55625e8259;p=jquery.git Fix 11004. getWH() box-sizing:border-box includes padding and border. --- diff --git a/src/css.js b/src/css.js index afbf96afb..a4d31a62c 100644 --- a/src/css.js +++ b/src/css.js @@ -272,15 +272,14 @@ curCSS = getComputedStyle || currentStyle; function getWidthOrHeight( elem, name, extra ) { - // Start with offset property + // Start with offset property, which is equivalent to the border-box value var val = name === "width" ? elem.offsetWidth : elem.offsetHeight, i = name === "width" ? 1 : 0, len = 4, - usedOffset = true; + valueIsBorderBox = true, + isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box"; if ( val <= 0 ) { - usedOffset = false; - // Fall back to computed then uncomputed css if necessary val = curCSS( elem, name ); if ( val < 0 || val == null ) { @@ -292,34 +291,47 @@ function getWidthOrHeight( elem, name, extra ) { return val; } + // we need the check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] ); + // Normalize "", auto, and prepare for extra val = parseFloat( val ) || 0; } - //if we're using border-box, the css width/height value behaves like the offsetWidth/Height property! - if ( usedOffset || ( jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box" ) ) { - if ( extra !== "border" ) { - for ( ; i < len; i += 2 ) { - if ( !extra ) { - val -= parseFloat( jQuery.css( elem, "padding" + cssExpand[ i ] ) ) || 0; + // determine which box-sizing width we're supposed to be getting + if ( !extra ) { + extra = isBorderBox ? "border" : "content"; + } + + // if the measurement we need is already represented by the retrieved width + // there's no need to augment further + if ( extra !== (valueIsBorderBox ? "border" : "content") ) { + for ( ; i < len; i += 2 ) { + // both box models exclude margin, so add it if we want it + if ( extra === "margin" ) { + // we use jQuery.css instead of curCSS here + // because of the reliableMarginRight CSS hook! + val += parseFloat( jQuery.css( elem, extra + cssExpand[ i ] ) ) || 0; + } + + if ( valueIsBorderBox ) { + // border-box includes padding, so remove it if we want content + if ( extra === "content" ) { + val -= parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; } - if ( extra === "margin" ) { - val += parseFloat( jQuery.css( elem, extra + cssExpand[ i ] ) ) || 0; - } else { - val -= parseFloat( jQuery.css( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; + + // at this point, extra isnt border nor margin, so remove border + if ( extra !== "margin" ) { + val -= parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; } - } - } - } else { - // Add padding, border, margin - if ( extra ) { - for ( ; i < len; i += 2 ) { - val += parseFloat( jQuery.css( elem, "padding" + cssExpand[ i ] ) ) || 0; + } else { + // at this point, extra isnt content, so add padding + val += parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; + + // at this point, extra isnt content nor padding, so add border if ( extra !== "padding" ) { - val += parseFloat( jQuery.css( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; - } - if ( extra === "margin" ) { - val += parseFloat( jQuery.css( elem, extra + cssExpand[ i ] ) ) || 0; + val += parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; } } } diff --git a/src/dimensions.js b/src/dimensions.js index 1350b1fe3..9ea688d76 100644 --- a/src/dimensions.js +++ b/src/dimensions.js @@ -59,7 +59,7 @@ jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { // Get width or height on the element if ( value === undefined ) { - orig = jQuery.css( elem, type ); + orig = jQuery.css( elem, type, "content" ); ret = parseFloat( orig ); return jQuery.isNumeric( ret ) ? ret : orig; } diff --git a/src/support.js b/src/support.js index ccf9d4315..8e50a15b7 100644 --- a/src/support.js +++ b/src/support.js @@ -91,7 +91,8 @@ jQuery.support = (function() { inlineBlockNeedsLayout: false, shrinkWrapBlocks: false, reliableMarginRight: true, - pixelMargin: true + pixelMargin: true, + boxSizingReliable: true }; // jQuery.boxModel DEPRECATED in 1.3, use jQuery.support.boxModel instead @@ -251,17 +252,17 @@ jQuery.support = (function() { support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); } - div.style.cssText = boxSizingPrefixes.join("box-sizing:border-box;") + "width:4px;padding:1px;border:1px;display:block"; + div.style.cssText = boxSizingPrefixes.join("box-sizing:border-box;") + "border:1px;width:4px;padding:1px;display:block;margin-top:1%;"; support.boxSizing = ( div.offsetWidth === 4 ); + if ( window.getComputedStyle ) { + support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; + support.pixelMargin = ( window.getComputedStyle( div, null ) || { marginTop: 0 } ).marginTop !== "1%"; + } offsetSupport = { doesNotIncludeMarginInBodyOffset: ( body.offsetTop !== conMarginTop ) }; - if ( window.getComputedStyle ) { - div.style.marginTop = "1%"; - support.pixelMargin = ( window.getComputedStyle( div, null ) || { marginTop: 0 } ).marginTop !== "1%"; - } if ( typeof container.style.zoom !== "undefined" ) { container.style.zoom = 1; diff --git a/test/unit/css.js b/test/unit/css.js index 8e7f8ec10..6d0b39f81 100644 --- a/test/unit/css.js +++ b/test/unit/css.js @@ -555,6 +555,18 @@ test("outerWidth(true) and css('margin') returning % instead of px in Webkit, se equal( el.outerWidth(true), 400, "outerWidth(true) and css('margin') returning % instead of px in Webkit, see #10639" ); }); +test("css('width') should respect box-sizing, see #11004", function() { + var el_disconnected = jQuery("
test
"), + el = el_disconnected.clone().appendTo("#qunit-fixture"), + width_initial = el.css("width"), + width_roundtrip = el.css("width", el.css("width")).css("width"), + width_initial_disconnected = el_disconnected.css("width"), + width_roundtrip_disconnected = el_disconnected.css("width", el_disconnected.css("width")).css("width"); + + equal( width_roundtrip, width_initial, "css('width') is not respecting box-sizing, see #11004"); + equal( width_roundtrip_disconnected, width_initial_disconnected, "css('width') is not respecting box-sizing for disconnected element, see #11004"); +}); + test( "cssHooks - expand", function() { expect( 15 ); var result,