Skip to content

Commit 7eb0019

Browse files
authored
CSS: Return undefined for whitespace-only CSS variable values (#5120)
The spec requires that CSS variable values are trimmed. In browsers that do this - mainly, Safari, but also Firefox if the value only has leading whitespace - we currently return undefined; in other browsers, we return an empty string as the logic to fall back to undefined happens before trimming. This commit adds another explicit callback to `undefined` to have it consistent across browsers. Also, more explicit comments about behaviors we need to work around in various browsers have been added. Closes gh-5120 Ref gh-5106
1 parent 2540075 commit 7eb0019

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

src/css/curCSS.js

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,37 @@ function curCSS( elem, name, computed ) {
1212

1313
// getPropertyValue is needed for `.css('--customProperty')` (gh-3144)
1414
if ( computed ) {
15-
ret = computed.getPropertyValue( name ) || computed[ name ];
1615

17-
// trim whitespace for custom property (issue gh-4926)
18-
if ( isCustomProp && ret !== undefined ) {
16+
// Support: IE <=9 - 11+
17+
// IE only supports `"float"` in `getPropertyValue`; in computed styles
18+
// it's only available as `"cssFloat"`. We no longer modify properties
19+
// sent to `.css()` apart from camelCasing, so we need to check both.
20+
// Normally, this would create difference in behavior: if
21+
// `getPropertyValue` returns an empty string, the value returned
22+
// by `.css()` would be `undefined`. This is usually the case for
23+
// disconnected elements. However, in IE even disconnected elements
24+
// with no styles return `"none"` for `getPropertyValue( "float" )`
25+
ret = computed.getPropertyValue( name ) || computed[ name ];
1926

27+
if ( isCustomProp && ret ) {
28+
29+
// Support: Firefox 105+, Chrome <=105+
30+
// Spec requires trimming whitespace for custom properties (gh-4926).
31+
// Firefox only trims leading whitespace. Chrome just collapses
32+
// both leading & trailing whitespace to a single space.
33+
//
34+
// Fall back to `undefined` if empty string returned.
35+
// This collapses a missing definition with property defined
36+
// and set to an empty string but there's no standard API
37+
// allowing us to differentiate them without a performance penalty
38+
// and returning `undefined` aligns with older jQuery.
39+
//
2040
// rtrim treats U+000D CARRIAGE RETURN and U+000C FORM FEED
2141
// as whitespace while CSS does not, but this is not a problem
2242
// because CSS preprocessing replaces them with U+000A LINE FEED
2343
// (which *is* CSS whitespace)
2444
// https://www.w3.org/TR/css-syntax-3/#input-preprocessing
25-
ret = ret.replace( rtrim, "$1" );
45+
ret = ret.replace( rtrim, "$1" ) || undefined;
2646
}
2747

2848
if ( ret === "" && !isAttached( elem ) ) {

test/unit/css.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1748,6 +1748,7 @@ QUnit.testUnlessIE( "css(--customProperty)", function( assert ) {
17481748
" --prop10:\f\r\n\t val10 \f\r\n\t;\n" +
17491749
" --prop11:\u000C\u000D\u000A\u0009\u0020val11\u0020\u0009\u000A\u000D\u000C;\n" +
17501750
" --prop12:\u000Bval12\u000B;\n" +
1751+
" --space: ;\n" +
17511752
" --empty:;\n" +
17521753
" }\n" +
17531754
"</style>"
@@ -1757,7 +1758,7 @@ QUnit.testUnlessIE( "css(--customProperty)", function( assert ) {
17571758
$elem = jQuery( "<div>" ).addClass( "test__customProperties" )
17581759
.appendTo( "#qunit-fixture" ),
17591760
webkitOrBlink = /\bsafari\b/i.test( navigator.userAgent ),
1760-
expected = 19;
1761+
expected = 20;
17611762

17621763
if ( webkitOrBlink ) {
17631764
expected -= 2;
@@ -1803,6 +1804,7 @@ QUnit.testUnlessIE( "css(--customProperty)", function( assert ) {
18031804
assert.equal( $elem.css( "--prop10" ), "val10", "Multiple preceding and following escaped unicode whitespace trimmed" );
18041805
assert.equal( $elem.css( "--prop11" ), "val11", "Multiple preceding and following unicode whitespace trimmed" );
18051806
assert.equal( $elem.css( "--prop12" ), "\u000Bval12\u000B", "Multiple preceding and following non-CSS whitespace reserved" );
1807+
assert.equal( $elem.css( "--space" ), undefined );
18061808
assert.equal( $elem.css( "--empty" ), undefined );
18071809
assert.equal( $elem.css( "--nonexistent" ), undefined );
18081810
} );

0 commit comments

Comments
 (0)