aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Gibson <richard.gibson@gmail.com>2017-07-10 12:35:03 -0400
committerGitHub <noreply@github.com>2017-07-10 12:35:03 -0400
commit3fcddd6e72e7e318c0b062e391d60867732318ae (patch)
tree964159e428d90159e9c44e2c825e1715b478b63a
parenta6a28d24c183d4252bd269d89b3ddc5f4ae88863 (diff)
downloadjquery-3fcddd6e72e7e318c0b062e391d60867732318ae.tar.gz
jquery-3fcddd6e72e7e318c0b062e391d60867732318ae.zip
Dimensions: Detect and account for content-box dimension mishandling
Fixes gh-3699 Closes gh-3700
-rw-r--r--src/css.js22
-rw-r--r--src/css/support.js21
-rw-r--r--test/unit/dimensions.js17
3 files changed, 44 insertions, 16 deletions
diff --git a/src/css.js b/src/css.js
index 5da9a3aea..79e06319c 100644
--- a/src/css.js
+++ b/src/css.js
@@ -148,10 +148,10 @@ function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computed
function getWidthOrHeight( elem, dimension, extra ) {
// Start with computed style
- var valueIsBorderBox,
- styles = getStyles( elem ),
+ var styles = getStyles( elem ),
val = curCSS( elem, dimension, styles ),
- isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
+ isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
+ valueIsBorderBox = isBorderBox;
// Computed unit is not pixels. Stop here and return.
if ( rnumnonpx.test( val ) ) {
@@ -160,7 +160,7 @@ function getWidthOrHeight( elem, dimension, extra ) {
// Check for style in case a browser which returns unreliable values
// for getComputedStyle silently falls back to the reliable elem.style
- valueIsBorderBox = isBorderBox &&
+ valueIsBorderBox = valueIsBorderBox &&
( support.boxSizingReliable() || val === elem.style[ dimension ] );
// Fall back to offsetWidth/Height when value is "auto"
@@ -367,14 +367,26 @@ jQuery.each( [ "height", "width" ], function( i, dimension ) {
set: function( elem, value, extra ) {
var matches,
styles = getStyles( elem ),
+ isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
subtract = extra && boxModelAdjustment(
elem,
dimension,
extra,
- jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
+ isBorderBox,
styles
);
+ // Account for unreliable border-box dimensions by comparing offset* to computed and
+ // faking a content-box to get border and padding (gh-3699)
+ if ( isBorderBox && !support.borderBoxReliable() ) {
+ subtract -= Math.ceil(
+ elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
+ parseFloat( styles[ dimension ] ) -
+ boxModelAdjustment( elem, dimension, "border", false, styles ) -
+ 0.5
+ );
+ }
+
// Convert to pixels if value adjustment is needed
if ( subtract && ( matches = rcssNum.exec( value ) ) &&
( matches[ 3 ] || "px" ) !== "px" ) {
diff --git a/src/css/support.js b/src/css/support.js
index 883d0e53e..7b7945fef 100644
--- a/src/css/support.js
+++ b/src/css/support.js
@@ -31,12 +31,16 @@ define( [
// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
reliableMarginLeftVal = divStyle.marginLeft === "2px";
- boxSizingReliableVal = divStyle.width === "4px";
+ boxSizingReliableVal = divStyle.width === "5px";
+
+ // Support: IE 9 only
+ // Detect misreporting of content dimensions for border-box elements (gh-3699)
+ borderBoxReliableVal = divStyle.width[ 0 ] === "5";
// Support: Android 4.0 - 4.3 only
// Some styles come back with percentage values, even though they shouldn't
div.style.marginRight = "50%";
- pixelMarginRightVal = divStyle.marginRight === "4px";
+ pixelMarginRightVal = divStyle.marginRight === "5px";
documentElement.removeChild( container );
@@ -45,7 +49,8 @@ define( [
div = null;
}
- var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,
+ var pixelPositionVal, boxSizingReliableVal, borderBoxReliableVal, pixelMarginRightVal,
+ reliableMarginLeftVal,
container = document.createElement( "div" ),
div = document.createElement( "div" );
@@ -60,19 +65,23 @@ define( [
div.cloneNode( true ).style.backgroundClip = "";
support.clearCloneStyle = div.style.backgroundClip === "content-box";
- container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
+ container.style.cssText = "border:0;width:10px;height:0;top:0;left:-9999px;" +
"padding:0;margin-top:1px;position:absolute";
container.appendChild( div );
jQuery.extend( support, {
- pixelPosition: function() {
+ borderBoxReliable: function() {
computeStyleTests();
- return pixelPositionVal;
+ return borderBoxReliableVal;
},
boxSizingReliable: function() {
computeStyleTests();
return boxSizingReliableVal;
},
+ pixelPosition: function() {
+ computeStyleTests();
+ return pixelPositionVal;
+ },
pixelMarginRight: function() {
computeStyleTests();
return pixelMarginRightVal;
diff --git a/test/unit/dimensions.js b/test/unit/dimensions.js
index 2ec5f3683..5db465868 100644
--- a/test/unit/dimensions.js
+++ b/test/unit/dimensions.js
@@ -585,7 +585,14 @@ QUnit.test( "interaction with scrollbars (gh-3589)", function( assert ) {
.css( borderBox )
.css( { "box-sizing": "border-box" } )
.appendTo( parent ),
- $boxes = jQuery( [ plainContentBox[ 0 ], contentBox[ 0 ], borderBox[ 0 ] ] );
+ $boxes = jQuery( [ plainContentBox[ 0 ], contentBox[ 0 ], borderBox[ 0 ] ] ),
+
+ // Support: IE 9 only
+ // Computed width seems to report content width even with "box-sizing: border-box", and
+ // "overflow: scroll" actually _shrinks_ the element (gh-3699).
+ borderBoxLoss =
+ borderBox.clone().css( { overflow: "auto" } ).appendTo( parent )[ 0 ].offsetWidth -
+ borderBox[ 0 ].offsetWidth;
for ( i = 0; i < 3; i++ ) {
if ( i === 1 ) {
@@ -616,13 +623,13 @@ QUnit.test( "interaction with scrollbars (gh-3589)", function( assert ) {
assert.equal( contentBox.outerHeight(), size + 2 * padding + 2 * borderWidth,
"content-box outerHeight includes scroll gutter" + suffix );
- assert.equal( borderBox.innerWidth(), size - 2 * borderWidth,
+ assert.equal( borderBox.innerWidth(), size - borderBoxLoss - 2 * borderWidth,
"border-box innerWidth includes scroll gutter" + suffix );
- assert.equal( borderBox.innerHeight(), size - 2 * borderWidth,
+ assert.equal( borderBox.innerHeight(), size - borderBoxLoss - 2 * borderWidth,
"border-box innerHeight includes scroll gutter" + suffix );
- assert.equal( borderBox.outerWidth(), size,
+ assert.equal( borderBox.outerWidth(), size - borderBoxLoss,
"border-box outerWidth includes scroll gutter" + suffix );
- assert.equal( borderBox.outerHeight(), size,
+ assert.equal( borderBox.outerHeight(), size - borderBoxLoss,
"border-box outerHeight includes scroll gutter" + suffix );
}
} );