🌐 AI搜索 & 代理 主页
Skip to content

Commit 1cda578

Browse files
committed
CSS: Don't automatically add "px" to properties with a few exceptions
Fixes gh-2795 Ref gh-4009
1 parent f8c1e90 commit 1cda578

File tree

5 files changed

+128
-27
lines changed

5 files changed

+128
-27
lines changed

src/css.js

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ define( [
77
"./var/rcssNum",
88
"./css/var/rnumnonpx",
99
"./css/var/cssExpand",
10+
"./css/isAutoPx",
1011
"./css/var/getStyles",
1112
"./css/var/swap",
1213
"./css/curCSS",
@@ -19,7 +20,7 @@ define( [
1920
"./core/ready",
2021
"./selector" // contains
2122
], function( jQuery, pnum, access, camelCase, document, rcssNum, rnumnonpx, cssExpand,
22-
getStyles, swap, curCSS, adjustCSS, addGetHookIf, support, finalPropName ) {
23+
isAutoPx, getStyles, swap, curCSS, adjustCSS, addGetHookIf, support, finalPropName ) {
2324

2425
"use strict";
2526

@@ -183,23 +184,6 @@ jQuery.extend( {
183184
}
184185
},
185186

186-
// Don't automatically add "px" to these possibly-unitless properties
187-
cssNumber: {
188-
"animationIterationCount": true,
189-
"columnCount": true,
190-
"fillOpacity": true,
191-
"flexGrow": true,
192-
"flexShrink": true,
193-
"fontWeight": true,
194-
"lineHeight": true,
195-
"opacity": true,
196-
"order": true,
197-
"orphans": true,
198-
"widows": true,
199-
"zIndex": true,
200-
"zoom": true
201-
},
202-
203187
// Add in properties whose names you wish to fix before
204188
// setting or getting the value
205189
cssProps: {},
@@ -245,9 +229,9 @@ jQuery.extend( {
245229
return;
246230
}
247231

248-
// If a number was passed in, add the unit (except for certain CSS properties)
232+
// If the value is a number, add `px` for certain CSS properties
249233
if ( type === "number" ) {
250-
value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
234+
value += ret && ret[ 3 ] || ( isAutoPx( origName ) ? "px" : "" );
251235
}
252236

253237
// background-* props affect original clone's values

src/css/adjustCSS.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
define( [
22
"../core",
3+
"./isAutoPx",
34
"../var/rcssNum"
4-
], function( jQuery, rcssNum ) {
5+
], function( jQuery, isAutoPx, rcssNum ) {
56

67
"use strict";
78

@@ -16,11 +17,11 @@ function adjustCSS( elem, prop, valueParts, tween ) {
1617
return jQuery.css( elem, prop, "" );
1718
},
1819
initial = currentValue(),
19-
unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
20+
unit = valueParts && valueParts[ 3 ] || ( isAutoPx( prop ) ? "px" : "" ),
2021

2122
// Starting value computation is required for potential unit mismatches
2223
initialInUnit = elem.nodeType &&
23-
( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
24+
( !isAutoPx( prop ) || unit !== "px" && +initial ) &&
2425
rcssNum.exec( jQuery.css( elem, prop ) );
2526

2627
if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {

src/css/isAutoPx.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
define( function() {
2+
3+
"use strict";
4+
5+
var ralphaStart = /^[a-z]/,
6+
7+
// The regex visualized:
8+
//
9+
// /----------\
10+
// | | /-------\
11+
// | / Top \ | | |
12+
// /--- Border ---+-| Right |-+---+- Width -+---\
13+
// | | Bottom | |
14+
// | \ Left / |
15+
// | |
16+
// | /----------\ |
17+
// | /-------------\ | | |- END
18+
// | | | | / Top \ | |
19+
// | | / Margin \ | | | Right | | |
20+
// |---------+-| |-+---+-| Bottom |-+----|
21+
// | \ Padding / \ Left / |
22+
// BEGIN -| |
23+
// | /---------\ |
24+
// | | | |
25+
// | | / Min \ | / Width \ |
26+
// \--------------+-| |-+---| |---/
27+
// \ Max / \ Height /
28+
rautoPx = /^(?:Border(?:Top|Right|Bottom|Left)?(?:Width|)|(?:Margin|Padding)?(?:Top|Right|Bottom|Left)?|(?:Min|Max)?(?:Width|Height))$/;
29+
30+
function isAutoPx( prop ) {
31+
32+
// The first test is used to ensure that:
33+
// 1. The prop starts with a lowercase letter (as we uppercase it for the second regex).
34+
// 2. The prop is not empty.
35+
return ralphaStart.test( prop ) &&
36+
rautoPx.test( prop[ 0 ].toUpperCase() + prop.slice( 1 ) );
37+
};
38+
39+
return isAutoPx;
40+
41+
} );

src/effects/Tween.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
define( [
22
"../core",
3+
"../css/isAutoPx",
34
"../css/finalPropName",
45

56
"../css"
6-
], function( jQuery, finalPropName ) {
7+
], function( jQuery, isAutoPx, finalPropName ) {
78

89
"use strict";
910

@@ -21,7 +22,7 @@ Tween.prototype = {
2122
this.options = options;
2223
this.start = this.now = this.cur();
2324
this.end = end;
24-
this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
25+
this.unit = unit || ( isAutoPx( prop ) ? "px" : "" );
2526
},
2627
cur: function() {
2728
var hooks = Tween.propHooks[ this.prop ];

test/unit/css.js

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,14 +1118,17 @@ if ( jQuery.fn.offset ) {
11181118
}
11191119

11201120
QUnit.test( "Do not append px (#9548, #12990, #2792)", function( assert ) {
1121-
assert.expect( 3 );
1121+
assert.expect( 4 );
11221122

11231123
var $div = jQuery( "<div>" ).appendTo( "#qunit-fixture" );
11241124

11251125
$div.css( "fill-opacity", 1 );
1126-
11271126
assert.equal( $div.css( "fill-opacity" ), 1, "Do not append px to 'fill-opacity'" );
11281127

1128+
$div.css( "font-size", "27px" );
1129+
$div.css( "line-height", 2 );
1130+
assert.equal( $div.css( "line-height" ), "54px", "Do not append px to 'line-height'" );
1131+
11291132
$div.css( "column-count", 1 );
11301133
if ( $div.css( "column-count" ) !== undefined ) {
11311134
assert.equal( $div.css( "column-count" ), 1, "Do not append px to 'column-count'" );
@@ -1143,6 +1146,77 @@ QUnit.test( "Do not append px (#9548, #12990, #2792)", function( assert ) {
11431146
}
11441147
} );
11451148

1149+
QUnit.test( "Do not append px to most properties not accepting integer values", function( assert ) {
1150+
assert.expect( 3 );
1151+
1152+
var $div = jQuery( "<div>" ).appendTo( "#qunit-fixture" );
1153+
1154+
$div.css( "font-size", "27px" );
1155+
1156+
$div.css( "font-size", 2 );
1157+
assert.equal( $div.css( "font-size" ), "27px", "Do not append px to 'font-size'" );
1158+
1159+
$div.css( "fontSize", 2 );
1160+
assert.equal( $div.css( "fontSize" ), "27px", "Do not append px to 'fontSize'" );
1161+
1162+
$div.css( "letter-spacing", "2px" );
1163+
$div.css( "letter-spacing", 3 );
1164+
assert.equal( $div.css( "letter-spacing" ), "2px", "Do not append px to 'letter-spacing'" );
1165+
} );
1166+
1167+
QUnit.test( "Append px to whitelisted properties", function( assert ) {
1168+
var prop,
1169+
$div = jQuery( "<div>" ).appendTo( "#qunit-fixture" ),
1170+
whitelist = {
1171+
margin: undefined,
1172+
marginTop: undefined,
1173+
marginRight: undefined,
1174+
marginBottom: undefined,
1175+
marginLeft: undefined,
1176+
padding: undefined,
1177+
paddingTop: undefined,
1178+
paddingRight: undefined,
1179+
paddingBottom: undefined,
1180+
paddingLeft: undefined,
1181+
top: undefined,
1182+
right: undefined,
1183+
bottom: undefined,
1184+
left: undefined,
1185+
width: undefined,
1186+
height: undefined,
1187+
minWidth: undefined,
1188+
minHeight: undefined,
1189+
maxWidth: undefined,
1190+
maxHeight: undefined,
1191+
border: "borderTopWidth",
1192+
borderWidth: "borderTopWidth",
1193+
borderTop: "borderTopWidth",
1194+
borderTopWidth: "borderTopWidth",
1195+
borderRight: "borderRightWidth",
1196+
borderRightWidth: "borderRightWidth",
1197+
borderBottom: "borderBottomWidth",
1198+
borderBottomWidth: "borderBottomWidth",
1199+
borderLeft: "borderLeftWidth",
1200+
borderLeftWidth: "borderLeftWidth"
1201+
};
1202+
1203+
assert.expect( ( Object.keys( whitelist ).length ) * 2 );
1204+
1205+
for ( prop in whitelist ) {
1206+
var propToCheck = whitelist[ prop ] || prop,
1207+
kebabProp = prop.replace( /[A-Z]/g, function( match ) {
1208+
return "-" + match.toLowerCase();
1209+
} ),
1210+
kebabPropToCheck = propToCheck.replace( /[A-Z]/g, function( match ) {
1211+
return "-" + match.toLowerCase();
1212+
} );
1213+
$div.css( prop, 3 ).css( "border-style", "solid" );
1214+
assert.equal( $div.css( propToCheck ), "3px", "Append px to '" + prop + "'" );
1215+
$div.css( kebabProp, 3 ).css( "border-style", "solid" );
1216+
assert.equal( $div.css( kebabPropToCheck ), "3px", "Append px to '" + kebabProp + "'" );
1217+
}
1218+
} );
1219+
11461220
QUnit.test( "css('width') and css('height') should respect box-sizing, see #11004", function( assert ) {
11471221
assert.expect( 4 );
11481222

0 commit comments

Comments
 (0)