Permalink
Browse files

Dimensions: Detect and account for content-box dimension mishandling

Fixes gh-3699
Closes gh-3700
  • Loading branch information...
gibson042 committed Jul 10, 2017
1 parent a6a28d2 commit 3fcddd6e72e7e318c0b062e391d60867732318ae
Showing with 44 additions and 16 deletions.
  1. +17 −5 src/css.js
  2. +15 −6 src/css/support.js
  3. +12 −5 test/unit/dimensions.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" ) {
@@ -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;
@@ -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 );
}
} );

1 comment on commit 3fcddd6

@Krinkle

This comment has been minimized.

Member

Krinkle commented on 3fcddd6 Jul 18, 2017

This commit appears to have broken the support tests in all browsers. Still the case on latest master.

See: #3730


It also broke the dimensions tests in IE 10 and IE 11.

See: #3731

Please sign in to comment.